Commit 624f7979058b84cbf81c76d45f302ce757b213ca
1 parent
afd7cd92
Make signal queues per thread.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4635 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
204 additions
and
173 deletions
linux-user/main.c
@@ -230,7 +230,7 @@ void cpu_loop(CPUX86State *env) | @@ -230,7 +230,7 @@ void cpu_loop(CPUX86State *env) | ||
230 | info.si_errno = 0; | 230 | info.si_errno = 0; |
231 | info.si_code = TARGET_SI_KERNEL; | 231 | info.si_code = TARGET_SI_KERNEL; |
232 | info._sifields._sigfault._addr = 0; | 232 | info._sifields._sigfault._addr = 0; |
233 | - queue_signal(info.si_signo, &info); | 233 | + queue_signal(env, info.si_signo, &info); |
234 | break; | 234 | break; |
235 | case EXCP0D_GPF: | 235 | case EXCP0D_GPF: |
236 | /* XXX: potential problem if ABI32 */ | 236 | /* XXX: potential problem if ABI32 */ |
@@ -244,7 +244,7 @@ void cpu_loop(CPUX86State *env) | @@ -244,7 +244,7 @@ void cpu_loop(CPUX86State *env) | ||
244 | info.si_errno = 0; | 244 | info.si_errno = 0; |
245 | info.si_code = TARGET_SI_KERNEL; | 245 | info.si_code = TARGET_SI_KERNEL; |
246 | info._sifields._sigfault._addr = 0; | 246 | info._sifields._sigfault._addr = 0; |
247 | - queue_signal(info.si_signo, &info); | 247 | + queue_signal(env, info.si_signo, &info); |
248 | } | 248 | } |
249 | break; | 249 | break; |
250 | case EXCP0E_PAGE: | 250 | case EXCP0E_PAGE: |
@@ -255,7 +255,7 @@ void cpu_loop(CPUX86State *env) | @@ -255,7 +255,7 @@ void cpu_loop(CPUX86State *env) | ||
255 | else | 255 | else |
256 | info.si_code = TARGET_SEGV_ACCERR; | 256 | info.si_code = TARGET_SEGV_ACCERR; |
257 | info._sifields._sigfault._addr = env->cr[2]; | 257 | info._sifields._sigfault._addr = env->cr[2]; |
258 | - queue_signal(info.si_signo, &info); | 258 | + queue_signal(env, info.si_signo, &info); |
259 | break; | 259 | break; |
260 | case EXCP00_DIVZ: | 260 | case EXCP00_DIVZ: |
261 | #ifndef TARGET_X86_64 | 261 | #ifndef TARGET_X86_64 |
@@ -269,7 +269,7 @@ void cpu_loop(CPUX86State *env) | @@ -269,7 +269,7 @@ void cpu_loop(CPUX86State *env) | ||
269 | info.si_errno = 0; | 269 | info.si_errno = 0; |
270 | info.si_code = TARGET_FPE_INTDIV; | 270 | info.si_code = TARGET_FPE_INTDIV; |
271 | info._sifields._sigfault._addr = env->eip; | 271 | info._sifields._sigfault._addr = env->eip; |
272 | - queue_signal(info.si_signo, &info); | 272 | + queue_signal(env, info.si_signo, &info); |
273 | } | 273 | } |
274 | break; | 274 | break; |
275 | case EXCP01_SSTP: | 275 | case EXCP01_SSTP: |
@@ -289,7 +289,7 @@ void cpu_loop(CPUX86State *env) | @@ -289,7 +289,7 @@ void cpu_loop(CPUX86State *env) | ||
289 | info.si_code = TARGET_SI_KERNEL; | 289 | info.si_code = TARGET_SI_KERNEL; |
290 | info._sifields._sigfault._addr = 0; | 290 | info._sifields._sigfault._addr = 0; |
291 | } | 291 | } |
292 | - queue_signal(info.si_signo, &info); | 292 | + queue_signal(env, info.si_signo, &info); |
293 | } | 293 | } |
294 | break; | 294 | break; |
295 | case EXCP04_INTO: | 295 | case EXCP04_INTO: |
@@ -304,7 +304,7 @@ void cpu_loop(CPUX86State *env) | @@ -304,7 +304,7 @@ void cpu_loop(CPUX86State *env) | ||
304 | info.si_errno = 0; | 304 | info.si_errno = 0; |
305 | info.si_code = TARGET_SI_KERNEL; | 305 | info.si_code = TARGET_SI_KERNEL; |
306 | info._sifields._sigfault._addr = 0; | 306 | info._sifields._sigfault._addr = 0; |
307 | - queue_signal(info.si_signo, &info); | 307 | + queue_signal(env, info.si_signo, &info); |
308 | } | 308 | } |
309 | break; | 309 | break; |
310 | case EXCP06_ILLOP: | 310 | case EXCP06_ILLOP: |
@@ -312,7 +312,7 @@ void cpu_loop(CPUX86State *env) | @@ -312,7 +312,7 @@ void cpu_loop(CPUX86State *env) | ||
312 | info.si_errno = 0; | 312 | info.si_errno = 0; |
313 | info.si_code = TARGET_ILL_ILLOPN; | 313 | info.si_code = TARGET_ILL_ILLOPN; |
314 | info._sifields._sigfault._addr = env->eip; | 314 | info._sifields._sigfault._addr = env->eip; |
315 | - queue_signal(info.si_signo, &info); | 315 | + queue_signal(env, info.si_signo, &info); |
316 | break; | 316 | break; |
317 | case EXCP_INTERRUPT: | 317 | case EXCP_INTERRUPT: |
318 | /* just indicate that signals should be handled asap */ | 318 | /* just indicate that signals should be handled asap */ |
@@ -327,7 +327,7 @@ void cpu_loop(CPUX86State *env) | @@ -327,7 +327,7 @@ void cpu_loop(CPUX86State *env) | ||
327 | info.si_signo = sig; | 327 | info.si_signo = sig; |
328 | info.si_errno = 0; | 328 | info.si_errno = 0; |
329 | info.si_code = TARGET_TRAP_BRKPT; | 329 | info.si_code = TARGET_TRAP_BRKPT; |
330 | - queue_signal(info.si_signo, &info); | 330 | + queue_signal(env, info.si_signo, &info); |
331 | } | 331 | } |
332 | } | 332 | } |
333 | break; | 333 | break; |
@@ -441,7 +441,7 @@ void cpu_loop(CPUARMState *env) | @@ -441,7 +441,7 @@ void cpu_loop(CPUARMState *env) | ||
441 | info.si_errno = 0; | 441 | info.si_errno = 0; |
442 | info.si_code = TARGET_ILL_ILLOPN; | 442 | info.si_code = TARGET_ILL_ILLOPN; |
443 | info._sifields._sigfault._addr = env->regs[15]; | 443 | info._sifields._sigfault._addr = env->regs[15]; |
444 | - queue_signal(info.si_signo, &info); | 444 | + queue_signal(env, info.si_signo, &info); |
445 | } else if (rc < 0) { /* FP exception */ | 445 | } else if (rc < 0) { /* FP exception */ |
446 | int arm_fpe=0; | 446 | int arm_fpe=0; |
447 | 447 | ||
@@ -472,7 +472,7 @@ void cpu_loop(CPUARMState *env) | @@ -472,7 +472,7 @@ void cpu_loop(CPUARMState *env) | ||
472 | if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV; | 472 | if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV; |
473 | 473 | ||
474 | info._sifields._sigfault._addr = env->regs[15]; | 474 | info._sifields._sigfault._addr = env->regs[15]; |
475 | - queue_signal(info.si_signo, &info); | 475 | + queue_signal(env, info.si_signo, &info); |
476 | } else { | 476 | } else { |
477 | env->regs[15] += 4; | 477 | env->regs[15] += 4; |
478 | } | 478 | } |
@@ -584,7 +584,7 @@ void cpu_loop(CPUARMState *env) | @@ -584,7 +584,7 @@ void cpu_loop(CPUARMState *env) | ||
584 | /* XXX: check env->error_code */ | 584 | /* XXX: check env->error_code */ |
585 | info.si_code = TARGET_SEGV_MAPERR; | 585 | info.si_code = TARGET_SEGV_MAPERR; |
586 | info._sifields._sigfault._addr = addr; | 586 | info._sifields._sigfault._addr = addr; |
587 | - queue_signal(info.si_signo, &info); | 587 | + queue_signal(env, info.si_signo, &info); |
588 | } | 588 | } |
589 | break; | 589 | break; |
590 | case EXCP_DEBUG: | 590 | case EXCP_DEBUG: |
@@ -597,7 +597,7 @@ void cpu_loop(CPUARMState *env) | @@ -597,7 +597,7 @@ void cpu_loop(CPUARMState *env) | ||
597 | info.si_signo = sig; | 597 | info.si_signo = sig; |
598 | info.si_errno = 0; | 598 | info.si_errno = 0; |
599 | info.si_code = TARGET_TRAP_BRKPT; | 599 | info.si_code = TARGET_TRAP_BRKPT; |
600 | - queue_signal(info.si_signo, &info); | 600 | + queue_signal(env, info.si_signo, &info); |
601 | } | 601 | } |
602 | } | 602 | } |
603 | break; | 603 | break; |
@@ -780,7 +780,7 @@ void cpu_loop (CPUSPARCState *env) | @@ -780,7 +780,7 @@ void cpu_loop (CPUSPARCState *env) | ||
780 | /* XXX: check env->error_code */ | 780 | /* XXX: check env->error_code */ |
781 | info.si_code = TARGET_SEGV_MAPERR; | 781 | info.si_code = TARGET_SEGV_MAPERR; |
782 | info._sifields._sigfault._addr = env->mmuregs[4]; | 782 | info._sifields._sigfault._addr = env->mmuregs[4]; |
783 | - queue_signal(info.si_signo, &info); | 783 | + queue_signal(env, info.si_signo, &info); |
784 | } | 784 | } |
785 | break; | 785 | break; |
786 | #else | 786 | #else |
@@ -801,7 +801,7 @@ void cpu_loop (CPUSPARCState *env) | @@ -801,7 +801,7 @@ void cpu_loop (CPUSPARCState *env) | ||
801 | info._sifields._sigfault._addr = env->dmmuregs[4]; | 801 | info._sifields._sigfault._addr = env->dmmuregs[4]; |
802 | else | 802 | else |
803 | info._sifields._sigfault._addr = env->tsptr->tpc; | 803 | info._sifields._sigfault._addr = env->tsptr->tpc; |
804 | - queue_signal(info.si_signo, &info); | 804 | + queue_signal(env, info.si_signo, &info); |
805 | } | 805 | } |
806 | break; | 806 | break; |
807 | #ifndef TARGET_ABI32 | 807 | #ifndef TARGET_ABI32 |
@@ -828,7 +828,7 @@ void cpu_loop (CPUSPARCState *env) | @@ -828,7 +828,7 @@ void cpu_loop (CPUSPARCState *env) | ||
828 | info.si_signo = sig; | 828 | info.si_signo = sig; |
829 | info.si_errno = 0; | 829 | info.si_errno = 0; |
830 | info.si_code = TARGET_TRAP_BRKPT; | 830 | info.si_code = TARGET_TRAP_BRKPT; |
831 | - queue_signal(info.si_signo, &info); | 831 | + queue_signal(env, info.si_signo, &info); |
832 | } | 832 | } |
833 | } | 833 | } |
834 | break; | 834 | break; |
@@ -949,7 +949,7 @@ void cpu_loop(CPUPPCState *env) | @@ -949,7 +949,7 @@ void cpu_loop(CPUPPCState *env) | ||
949 | break; | 949 | break; |
950 | } | 950 | } |
951 | info._sifields._sigfault._addr = env->nip; | 951 | info._sifields._sigfault._addr = env->nip; |
952 | - queue_signal(info.si_signo, &info); | 952 | + queue_signal(env, info.si_signo, &info); |
953 | break; | 953 | break; |
954 | case POWERPC_EXCP_ISI: /* Instruction storage exception */ | 954 | case POWERPC_EXCP_ISI: /* Instruction storage exception */ |
955 | EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n", | 955 | EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n", |
@@ -977,7 +977,7 @@ void cpu_loop(CPUPPCState *env) | @@ -977,7 +977,7 @@ void cpu_loop(CPUPPCState *env) | ||
977 | break; | 977 | break; |
978 | } | 978 | } |
979 | info._sifields._sigfault._addr = env->nip - 4; | 979 | info._sifields._sigfault._addr = env->nip - 4; |
980 | - queue_signal(info.si_signo, &info); | 980 | + queue_signal(env, info.si_signo, &info); |
981 | break; | 981 | break; |
982 | case POWERPC_EXCP_EXTERNAL: /* External input */ | 982 | case POWERPC_EXCP_EXTERNAL: /* External input */ |
983 | cpu_abort(env, "External interrupt while in user mode. " | 983 | cpu_abort(env, "External interrupt while in user mode. " |
@@ -990,7 +990,7 @@ void cpu_loop(CPUPPCState *env) | @@ -990,7 +990,7 @@ void cpu_loop(CPUPPCState *env) | ||
990 | info.si_errno = 0; | 990 | info.si_errno = 0; |
991 | info.si_code = TARGET_BUS_ADRALN; | 991 | info.si_code = TARGET_BUS_ADRALN; |
992 | info._sifields._sigfault._addr = env->nip - 4; | 992 | info._sifields._sigfault._addr = env->nip - 4; |
993 | - queue_signal(info.si_signo, &info); | 993 | + queue_signal(env, info.si_signo, &info); |
994 | break; | 994 | break; |
995 | case POWERPC_EXCP_PROGRAM: /* Program exception */ | 995 | case POWERPC_EXCP_PROGRAM: /* Program exception */ |
996 | /* XXX: check this */ | 996 | /* XXX: check this */ |
@@ -1083,7 +1083,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1083,7 +1083,7 @@ void cpu_loop(CPUPPCState *env) | ||
1083 | break; | 1083 | break; |
1084 | } | 1084 | } |
1085 | info._sifields._sigfault._addr = env->nip - 4; | 1085 | info._sifields._sigfault._addr = env->nip - 4; |
1086 | - queue_signal(info.si_signo, &info); | 1086 | + queue_signal(env, info.si_signo, &info); |
1087 | break; | 1087 | break; |
1088 | case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ | 1088 | case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ |
1089 | EXCP_DUMP(env, "No floating point allowed\n"); | 1089 | EXCP_DUMP(env, "No floating point allowed\n"); |
@@ -1091,7 +1091,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1091,7 +1091,7 @@ void cpu_loop(CPUPPCState *env) | ||
1091 | info.si_errno = 0; | 1091 | info.si_errno = 0; |
1092 | info.si_code = TARGET_ILL_COPROC; | 1092 | info.si_code = TARGET_ILL_COPROC; |
1093 | info._sifields._sigfault._addr = env->nip - 4; | 1093 | info._sifields._sigfault._addr = env->nip - 4; |
1094 | - queue_signal(info.si_signo, &info); | 1094 | + queue_signal(env, info.si_signo, &info); |
1095 | break; | 1095 | break; |
1096 | case POWERPC_EXCP_SYSCALL: /* System call exception */ | 1096 | case POWERPC_EXCP_SYSCALL: /* System call exception */ |
1097 | cpu_abort(env, "Syscall exception while in user mode. " | 1097 | cpu_abort(env, "Syscall exception while in user mode. " |
@@ -1103,7 +1103,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1103,7 +1103,7 @@ void cpu_loop(CPUPPCState *env) | ||
1103 | info.si_errno = 0; | 1103 | info.si_errno = 0; |
1104 | info.si_code = TARGET_ILL_COPROC; | 1104 | info.si_code = TARGET_ILL_COPROC; |
1105 | info._sifields._sigfault._addr = env->nip - 4; | 1105 | info._sifields._sigfault._addr = env->nip - 4; |
1106 | - queue_signal(info.si_signo, &info); | 1106 | + queue_signal(env, info.si_signo, &info); |
1107 | break; | 1107 | break; |
1108 | case POWERPC_EXCP_DECR: /* Decrementer exception */ | 1108 | case POWERPC_EXCP_DECR: /* Decrementer exception */ |
1109 | cpu_abort(env, "Decrementer interrupt while in user mode. " | 1109 | cpu_abort(env, "Decrementer interrupt while in user mode. " |
@@ -1135,7 +1135,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1135,7 +1135,7 @@ void cpu_loop(CPUPPCState *env) | ||
1135 | info.si_signo = sig; | 1135 | info.si_signo = sig; |
1136 | info.si_errno = 0; | 1136 | info.si_errno = 0; |
1137 | info.si_code = TARGET_TRAP_BRKPT; | 1137 | info.si_code = TARGET_TRAP_BRKPT; |
1138 | - queue_signal(info.si_signo, &info); | 1138 | + queue_signal(env, info.si_signo, &info); |
1139 | } | 1139 | } |
1140 | } | 1140 | } |
1141 | break; | 1141 | break; |
@@ -1145,7 +1145,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1145,7 +1145,7 @@ void cpu_loop(CPUPPCState *env) | ||
1145 | info.si_errno = 0; | 1145 | info.si_errno = 0; |
1146 | info.si_code = TARGET_ILL_COPROC; | 1146 | info.si_code = TARGET_ILL_COPROC; |
1147 | info._sifields._sigfault._addr = env->nip - 4; | 1147 | info._sifields._sigfault._addr = env->nip - 4; |
1148 | - queue_signal(info.si_signo, &info); | 1148 | + queue_signal(env, info.si_signo, &info); |
1149 | break; | 1149 | break; |
1150 | case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */ | 1150 | case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */ |
1151 | cpu_abort(env, "Embedded floating-point data IRQ not handled\n"); | 1151 | cpu_abort(env, "Embedded floating-point data IRQ not handled\n"); |
@@ -1209,7 +1209,7 @@ void cpu_loop(CPUPPCState *env) | @@ -1209,7 +1209,7 @@ void cpu_loop(CPUPPCState *env) | ||
1209 | info.si_errno = 0; | 1209 | info.si_errno = 0; |
1210 | info.si_code = TARGET_ILL_COPROC; | 1210 | info.si_code = TARGET_ILL_COPROC; |
1211 | info._sifields._sigfault._addr = env->nip - 4; | 1211 | info._sifields._sigfault._addr = env->nip - 4; |
1212 | - queue_signal(info.si_signo, &info); | 1212 | + queue_signal(env, info.si_signo, &info); |
1213 | break; | 1213 | break; |
1214 | case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */ | 1214 | case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */ |
1215 | cpu_abort(env, "Programable interval timer interrupt " | 1215 | cpu_abort(env, "Programable interval timer interrupt " |
@@ -1685,7 +1685,7 @@ void cpu_loop(CPUMIPSState *env) | @@ -1685,7 +1685,7 @@ void cpu_loop(CPUMIPSState *env) | ||
1685 | info.si_signo = TARGET_SIGILL; | 1685 | info.si_signo = TARGET_SIGILL; |
1686 | info.si_errno = 0; | 1686 | info.si_errno = 0; |
1687 | info.si_code = 0; | 1687 | info.si_code = 0; |
1688 | - queue_signal(info.si_signo, &info); | 1688 | + queue_signal(env, info.si_signo, &info); |
1689 | break; | 1689 | break; |
1690 | case EXCP_INTERRUPT: | 1690 | case EXCP_INTERRUPT: |
1691 | /* just indicate that signals should be handled asap */ | 1691 | /* just indicate that signals should be handled asap */ |
@@ -1700,7 +1700,7 @@ void cpu_loop(CPUMIPSState *env) | @@ -1700,7 +1700,7 @@ void cpu_loop(CPUMIPSState *env) | ||
1700 | info.si_signo = sig; | 1700 | info.si_signo = sig; |
1701 | info.si_errno = 0; | 1701 | info.si_errno = 0; |
1702 | info.si_code = TARGET_TRAP_BRKPT; | 1702 | info.si_code = TARGET_TRAP_BRKPT; |
1703 | - queue_signal(info.si_signo, &info); | 1703 | + queue_signal(env, info.si_signo, &info); |
1704 | } | 1704 | } |
1705 | } | 1705 | } |
1706 | break; | 1706 | break; |
@@ -1751,7 +1751,7 @@ void cpu_loop (CPUState *env) | @@ -1751,7 +1751,7 @@ void cpu_loop (CPUState *env) | ||
1751 | info.si_signo = sig; | 1751 | info.si_signo = sig; |
1752 | info.si_errno = 0; | 1752 | info.si_errno = 0; |
1753 | info.si_code = TARGET_TRAP_BRKPT; | 1753 | info.si_code = TARGET_TRAP_BRKPT; |
1754 | - queue_signal(info.si_signo, &info); | 1754 | + queue_signal(env, info.si_signo, &info); |
1755 | } | 1755 | } |
1756 | } | 1756 | } |
1757 | break; | 1757 | break; |
@@ -1761,7 +1761,7 @@ void cpu_loop (CPUState *env) | @@ -1761,7 +1761,7 @@ void cpu_loop (CPUState *env) | ||
1761 | info.si_errno = 0; | 1761 | info.si_errno = 0; |
1762 | info.si_code = TARGET_SEGV_MAPERR; | 1762 | info.si_code = TARGET_SEGV_MAPERR; |
1763 | info._sifields._sigfault._addr = env->tea; | 1763 | info._sifields._sigfault._addr = env->tea; |
1764 | - queue_signal(info.si_signo, &info); | 1764 | + queue_signal(env, info.si_signo, &info); |
1765 | break; | 1765 | break; |
1766 | 1766 | ||
1767 | default: | 1767 | default: |
@@ -1790,7 +1790,7 @@ void cpu_loop (CPUState *env) | @@ -1790,7 +1790,7 @@ void cpu_loop (CPUState *env) | ||
1790 | /* XXX: check env->error_code */ | 1790 | /* XXX: check env->error_code */ |
1791 | info.si_code = TARGET_SEGV_MAPERR; | 1791 | info.si_code = TARGET_SEGV_MAPERR; |
1792 | info._sifields._sigfault._addr = env->pregs[PR_EDA]; | 1792 | info._sifields._sigfault._addr = env->pregs[PR_EDA]; |
1793 | - queue_signal(info.si_signo, &info); | 1793 | + queue_signal(env, info.si_signo, &info); |
1794 | } | 1794 | } |
1795 | break; | 1795 | break; |
1796 | case EXCP_INTERRUPT: | 1796 | case EXCP_INTERRUPT: |
@@ -1818,7 +1818,7 @@ void cpu_loop (CPUState *env) | @@ -1818,7 +1818,7 @@ void cpu_loop (CPUState *env) | ||
1818 | info.si_signo = sig; | 1818 | info.si_signo = sig; |
1819 | info.si_errno = 0; | 1819 | info.si_errno = 0; |
1820 | info.si_code = TARGET_TRAP_BRKPT; | 1820 | info.si_code = TARGET_TRAP_BRKPT; |
1821 | - queue_signal(info.si_signo, &info); | 1821 | + queue_signal(env, info.si_signo, &info); |
1822 | } | 1822 | } |
1823 | } | 1823 | } |
1824 | break; | 1824 | break; |
@@ -1869,7 +1869,7 @@ void cpu_loop(CPUM68KState *env) | @@ -1869,7 +1869,7 @@ void cpu_loop(CPUM68KState *env) | ||
1869 | info.si_errno = 0; | 1869 | info.si_errno = 0; |
1870 | info.si_code = TARGET_ILL_ILLOPN; | 1870 | info.si_code = TARGET_ILL_ILLOPN; |
1871 | info._sifields._sigfault._addr = env->pc; | 1871 | info._sifields._sigfault._addr = env->pc; |
1872 | - queue_signal(info.si_signo, &info); | 1872 | + queue_signal(env, info.si_signo, &info); |
1873 | break; | 1873 | break; |
1874 | case EXCP_TRAP0: | 1874 | case EXCP_TRAP0: |
1875 | { | 1875 | { |
@@ -1896,7 +1896,7 @@ void cpu_loop(CPUM68KState *env) | @@ -1896,7 +1896,7 @@ void cpu_loop(CPUM68KState *env) | ||
1896 | /* XXX: check env->error_code */ | 1896 | /* XXX: check env->error_code */ |
1897 | info.si_code = TARGET_SEGV_MAPERR; | 1897 | info.si_code = TARGET_SEGV_MAPERR; |
1898 | info._sifields._sigfault._addr = env->mmu.ar; | 1898 | info._sifields._sigfault._addr = env->mmu.ar; |
1899 | - queue_signal(info.si_signo, &info); | 1899 | + queue_signal(env, info.si_signo, &info); |
1900 | } | 1900 | } |
1901 | break; | 1901 | break; |
1902 | case EXCP_DEBUG: | 1902 | case EXCP_DEBUG: |
@@ -1909,7 +1909,7 @@ void cpu_loop(CPUM68KState *env) | @@ -1909,7 +1909,7 @@ void cpu_loop(CPUM68KState *env) | ||
1909 | info.si_signo = sig; | 1909 | info.si_signo = sig; |
1910 | info.si_errno = 0; | 1910 | info.si_errno = 0; |
1911 | info.si_code = TARGET_TRAP_BRKPT; | 1911 | info.si_code = TARGET_TRAP_BRKPT; |
1912 | - queue_signal(info.si_signo, &info); | 1912 | + queue_signal(env, info.si_signo, &info); |
1913 | } | 1913 | } |
1914 | } | 1914 | } |
1915 | break; | 1915 | break; |
@@ -2000,7 +2000,7 @@ void cpu_loop (CPUState *env) | @@ -2000,7 +2000,7 @@ void cpu_loop (CPUState *env) | ||
2000 | info.si_signo = sig; | 2000 | info.si_signo = sig; |
2001 | info.si_errno = 0; | 2001 | info.si_errno = 0; |
2002 | info.si_code = TARGET_TRAP_BRKPT; | 2002 | info.si_code = TARGET_TRAP_BRKPT; |
2003 | - queue_signal(info.si_signo, &info); | 2003 | + queue_signal(env, info.si_signo, &info); |
2004 | } | 2004 | } |
2005 | } | 2005 | } |
2006 | break; | 2006 | break; |
@@ -2047,9 +2047,19 @@ void usage(void) | @@ -2047,9 +2047,19 @@ void usage(void) | ||
2047 | /* XXX: currently only used for async signals (see signal.c) */ | 2047 | /* XXX: currently only used for async signals (see signal.c) */ |
2048 | CPUState *global_env; | 2048 | CPUState *global_env; |
2049 | 2049 | ||
2050 | -/* used to free thread contexts */ | ||
2051 | -TaskState *first_task_state; | ||
2052 | - | 2050 | +void init_task_state(TaskState *ts) |
2051 | +{ | ||
2052 | + int i; | ||
2053 | + | ||
2054 | + memset(ts, 0, sizeof(TaskState)); | ||
2055 | + ts->used = 1; | ||
2056 | + ts->first_free = ts->sigqueue_table; | ||
2057 | + for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) { | ||
2058 | + ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1]; | ||
2059 | + } | ||
2060 | + ts->sigqueue_table[i].next = NULL; | ||
2061 | +} | ||
2062 | + | ||
2053 | int main(int argc, char **argv) | 2063 | int main(int argc, char **argv) |
2054 | { | 2064 | { |
2055 | const char *filename; | 2065 | const char *filename; |
@@ -2246,9 +2256,9 @@ int main(int argc, char **argv) | @@ -2246,9 +2256,9 @@ int main(int argc, char **argv) | ||
2246 | 2256 | ||
2247 | /* build Task State */ | 2257 | /* build Task State */ |
2248 | memset(ts, 0, sizeof(TaskState)); | 2258 | memset(ts, 0, sizeof(TaskState)); |
2249 | - env->opaque = ts; | ||
2250 | - ts->used = 1; | 2259 | + init_task_state(ts); |
2251 | ts->info = info; | 2260 | ts->info = info; |
2261 | + env->opaque = ts; | ||
2252 | env->user_mode_only = 1; | 2262 | env->user_mode_only = 1; |
2253 | 2263 | ||
2254 | #if defined(TARGET_I386) | 2264 | #if defined(TARGET_I386) |
linux-user/qemu.h
@@ -82,6 +82,20 @@ struct vm86_saved_state { | @@ -82,6 +82,20 @@ struct vm86_saved_state { | ||
82 | #include "nwfpe/fpa11.h" | 82 | #include "nwfpe/fpa11.h" |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | +#define MAX_SIGQUEUE_SIZE 1024 | ||
86 | + | ||
87 | +struct sigqueue { | ||
88 | + struct sigqueue *next; | ||
89 | + target_siginfo_t info; | ||
90 | +}; | ||
91 | + | ||
92 | +struct emulated_sigtable { | ||
93 | + int pending; /* true if signal is pending */ | ||
94 | + struct sigqueue *first; | ||
95 | + struct sigqueue info; /* in order to always have memory for the | ||
96 | + first signal, we put it here */ | ||
97 | +}; | ||
98 | + | ||
85 | /* NOTE: we force a big alignment so that the stack stored after is | 99 | /* NOTE: we force a big alignment so that the stack stored after is |
86 | aligned too */ | 100 | aligned too */ |
87 | typedef struct TaskState { | 101 | typedef struct TaskState { |
@@ -109,10 +123,16 @@ typedef struct TaskState { | @@ -109,10 +123,16 @@ typedef struct TaskState { | ||
109 | #endif | 123 | #endif |
110 | int used; /* non zero if used */ | 124 | int used; /* non zero if used */ |
111 | struct image_info *info; | 125 | struct image_info *info; |
126 | + | ||
127 | + struct emulated_sigtable sigtab[TARGET_NSIG]; | ||
128 | + struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ | ||
129 | + struct sigqueue *first_free; /* first free siginfo queue entry */ | ||
130 | + int signal_pending; /* non zero if a signal may be pending */ | ||
131 | + | ||
112 | uint8_t stack[0]; | 132 | uint8_t stack[0]; |
113 | } __attribute__((aligned(16))) TaskState; | 133 | } __attribute__((aligned(16))) TaskState; |
114 | 134 | ||
115 | -extern TaskState *first_task_state; | 135 | +void init_task_state(TaskState *ts); |
116 | extern const char *qemu_uname_release; | 136 | extern const char *qemu_uname_release; |
117 | 137 | ||
118 | /* ??? See if we can avoid exposing so much of the loader internals. */ | 138 | /* ??? See if we can avoid exposing so much of the loader internals. */ |
@@ -182,9 +202,9 @@ void print_syscall_ret(int num, abi_long arg1); | @@ -182,9 +202,9 @@ void print_syscall_ret(int num, abi_long arg1); | ||
182 | extern int do_strace; | 202 | extern int do_strace; |
183 | 203 | ||
184 | /* signal.c */ | 204 | /* signal.c */ |
185 | -void process_pending_signals(void *cpu_env); | 205 | +void process_pending_signals(CPUState *cpu_env); |
186 | void signal_init(void); | 206 | void signal_init(void); |
187 | -int queue_signal(int sig, target_siginfo_t *info); | 207 | +int queue_signal(CPUState *env, int sig, target_siginfo_t *info); |
188 | void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | 208 | void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); |
189 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); | 209 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); |
190 | int target_to_host_signal(int sig); | 210 | int target_to_host_signal(int sig); |
linux-user/signal.c
@@ -31,31 +31,13 @@ | @@ -31,31 +31,13 @@ | ||
31 | 31 | ||
32 | //#define DEBUG_SIGNAL | 32 | //#define DEBUG_SIGNAL |
33 | 33 | ||
34 | -#define MAX_SIGQUEUE_SIZE 1024 | ||
35 | - | ||
36 | -struct sigqueue { | ||
37 | - struct sigqueue *next; | ||
38 | - target_siginfo_t info; | ||
39 | -}; | ||
40 | - | ||
41 | -struct emulated_sigaction { | ||
42 | - struct target_sigaction sa; | ||
43 | - int pending; /* true if signal is pending */ | ||
44 | - struct sigqueue *first; | ||
45 | - struct sigqueue info; /* in order to always have memory for the | ||
46 | - first signal, we put it here */ | ||
47 | -}; | ||
48 | - | ||
49 | struct target_sigaltstack target_sigaltstack_used = { | 34 | struct target_sigaltstack target_sigaltstack_used = { |
50 | .ss_sp = 0, | 35 | .ss_sp = 0, |
51 | .ss_size = 0, | 36 | .ss_size = 0, |
52 | .ss_flags = TARGET_SS_DISABLE, | 37 | .ss_flags = TARGET_SS_DISABLE, |
53 | }; | 38 | }; |
54 | 39 | ||
55 | -static struct emulated_sigaction sigact_table[TARGET_NSIG]; | ||
56 | -static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ | ||
57 | -static struct sigqueue *first_free; /* first free siginfo queue entry */ | ||
58 | -static int signal_pending; /* non zero if a signal may be pending */ | 40 | +static struct target_sigaction sigact_table[TARGET_NSIG]; |
59 | 41 | ||
60 | static void host_signal_handler(int host_signum, siginfo_t *info, | 42 | static void host_signal_handler(int host_signum, siginfo_t *info, |
61 | void *puc); | 43 | void *puc); |
@@ -96,6 +78,12 @@ static uint8_t host_to_target_signal_table[65] = { | @@ -96,6 +78,12 @@ static uint8_t host_to_target_signal_table[65] = { | ||
96 | [SIGPWR] = TARGET_SIGPWR, | 78 | [SIGPWR] = TARGET_SIGPWR, |
97 | [SIGSYS] = TARGET_SIGSYS, | 79 | [SIGSYS] = TARGET_SIGSYS, |
98 | /* next signals stay the same */ | 80 | /* next signals stay the same */ |
81 | + /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with | ||
82 | + host libpthread signals. This assumes noone actually uses SIGRTMAX :-/ | ||
83 | + To fix this properly we need to do manual signal delivery multiplexed | ||
84 | + over a single host signal. */ | ||
85 | + [__SIGRTMIN] = __SIGRTMAX, | ||
86 | + [__SIGRTMAX] = __SIGRTMIN, | ||
99 | }; | 87 | }; |
100 | static uint8_t target_to_host_signal_table[65]; | 88 | static uint8_t target_to_host_signal_table[65]; |
101 | 89 | ||
@@ -278,7 +266,9 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) | @@ -278,7 +266,9 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) | ||
278 | void signal_init(void) | 266 | void signal_init(void) |
279 | { | 267 | { |
280 | struct sigaction act; | 268 | struct sigaction act; |
269 | + struct sigaction oact; | ||
281 | int i, j; | 270 | int i, j; |
271 | + int host_sig; | ||
282 | 272 | ||
283 | /* generate signal conversion tables */ | 273 | /* generate signal conversion tables */ |
284 | for(i = 1; i <= 64; i++) { | 274 | for(i = 1; i <= 64; i++) { |
@@ -292,36 +282,45 @@ void signal_init(void) | @@ -292,36 +282,45 @@ void signal_init(void) | ||
292 | 282 | ||
293 | /* set all host signal handlers. ALL signals are blocked during | 283 | /* set all host signal handlers. ALL signals are blocked during |
294 | the handlers to serialize them. */ | 284 | the handlers to serialize them. */ |
285 | + memset(sigact_table, 0, sizeof(sigact_table)); | ||
286 | + | ||
295 | sigfillset(&act.sa_mask); | 287 | sigfillset(&act.sa_mask); |
296 | act.sa_flags = SA_SIGINFO; | 288 | act.sa_flags = SA_SIGINFO; |
297 | act.sa_sigaction = host_signal_handler; | 289 | act.sa_sigaction = host_signal_handler; |
298 | - for(i = 1; i < NSIG; i++) { | ||
299 | - sigaction(i, &act, NULL); | 290 | + for(i = 1; i <= TARGET_NSIG; i++) { |
291 | + host_sig = target_to_host_signal(i); | ||
292 | + sigaction(host_sig, NULL, &oact); | ||
293 | + if (oact.sa_sigaction == (void *)SIG_IGN) { | ||
294 | + sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN; | ||
295 | + } else if (oact.sa_sigaction == (void *)SIG_DFL) { | ||
296 | + sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL; | ||
297 | + } | ||
298 | + /* If there's already a handler installed then something has | ||
299 | + gone horribly wrong, so don't even try to handle that case. */ | ||
300 | + /* Install some handlers for our own use. */ | ||
301 | + if (host_sig == SIGSEGV || host_sig == SIGBUS) { | ||
302 | + sigaction(host_sig, &act, NULL); | ||
303 | + } | ||
300 | } | 304 | } |
301 | - | ||
302 | - memset(sigact_table, 0, sizeof(sigact_table)); | ||
303 | - | ||
304 | - first_free = &sigqueue_table[0]; | ||
305 | - for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) | ||
306 | - sigqueue_table[i].next = &sigqueue_table[i + 1]; | ||
307 | - sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL; | ||
308 | } | 305 | } |
309 | 306 | ||
310 | /* signal queue handling */ | 307 | /* signal queue handling */ |
311 | 308 | ||
312 | -static inline struct sigqueue *alloc_sigqueue(void) | 309 | +static inline struct sigqueue *alloc_sigqueue(CPUState *env) |
313 | { | 310 | { |
314 | - struct sigqueue *q = first_free; | 311 | + TaskState *ts = env->opaque; |
312 | + struct sigqueue *q = ts->first_free; | ||
315 | if (!q) | 313 | if (!q) |
316 | return NULL; | 314 | return NULL; |
317 | - first_free = q->next; | 315 | + ts->first_free = q->next; |
318 | return q; | 316 | return q; |
319 | } | 317 | } |
320 | 318 | ||
321 | -static inline void free_sigqueue(struct sigqueue *q) | 319 | +static inline void free_sigqueue(CPUState *env, struct sigqueue *q) |
322 | { | 320 | { |
323 | - q->next = first_free; | ||
324 | - first_free = q; | 321 | + TaskState *ts = env->opaque; |
322 | + q->next = ts->first_free; | ||
323 | + ts->first_free = q; | ||
325 | } | 324 | } |
326 | 325 | ||
327 | /* abort execution with signal */ | 326 | /* abort execution with signal */ |
@@ -347,9 +346,10 @@ void __attribute((noreturn)) force_sig(int sig) | @@ -347,9 +346,10 @@ void __attribute((noreturn)) force_sig(int sig) | ||
347 | 346 | ||
348 | /* queue a signal so that it will be send to the virtual CPU as soon | 347 | /* queue a signal so that it will be send to the virtual CPU as soon |
349 | as possible */ | 348 | as possible */ |
350 | -int queue_signal(int sig, target_siginfo_t *info) | 349 | +int queue_signal(CPUState *env, int sig, target_siginfo_t *info) |
351 | { | 350 | { |
352 | - struct emulated_sigaction *k; | 351 | + TaskState *ts = env->opaque; |
352 | + struct emulated_sigtable *k; | ||
353 | struct sigqueue *q, **pq; | 353 | struct sigqueue *q, **pq; |
354 | abi_ulong handler; | 354 | abi_ulong handler; |
355 | 355 | ||
@@ -357,8 +357,8 @@ int queue_signal(int sig, target_siginfo_t *info) | @@ -357,8 +357,8 @@ int queue_signal(int sig, target_siginfo_t *info) | ||
357 | fprintf(stderr, "queue_signal: sig=%d\n", | 357 | fprintf(stderr, "queue_signal: sig=%d\n", |
358 | sig); | 358 | sig); |
359 | #endif | 359 | #endif |
360 | - k = &sigact_table[sig - 1]; | ||
361 | - handler = k->sa._sa_handler; | 360 | + k = &ts->sigtab[sig - 1]; |
361 | + handler = sigact_table[sig - 1]._sa_handler; | ||
362 | if (handler == TARGET_SIG_DFL) { | 362 | if (handler == TARGET_SIG_DFL) { |
363 | /* default handler : ignore some signal. The other are fatal */ | 363 | /* default handler : ignore some signal. The other are fatal */ |
364 | if (sig != TARGET_SIGCHLD && | 364 | if (sig != TARGET_SIGCHLD && |
@@ -386,7 +386,7 @@ int queue_signal(int sig, target_siginfo_t *info) | @@ -386,7 +386,7 @@ int queue_signal(int sig, target_siginfo_t *info) | ||
386 | /* first signal */ | 386 | /* first signal */ |
387 | q = &k->info; | 387 | q = &k->info; |
388 | } else { | 388 | } else { |
389 | - q = alloc_sigqueue(); | 389 | + q = alloc_sigqueue(env); |
390 | if (!q) | 390 | if (!q) |
391 | return -EAGAIN; | 391 | return -EAGAIN; |
392 | while (*pq != NULL) | 392 | while (*pq != NULL) |
@@ -398,7 +398,7 @@ int queue_signal(int sig, target_siginfo_t *info) | @@ -398,7 +398,7 @@ int queue_signal(int sig, target_siginfo_t *info) | ||
398 | q->next = NULL; | 398 | q->next = NULL; |
399 | k->pending = 1; | 399 | k->pending = 1; |
400 | /* signal that a new signal is pending */ | 400 | /* signal that a new signal is pending */ |
401 | - signal_pending = 1; | 401 | + ts->signal_pending = 1; |
402 | return 1; /* indicates that the signal was queued */ | 402 | return 1; /* indicates that the signal was queued */ |
403 | } | 403 | } |
404 | } | 404 | } |
@@ -424,7 +424,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | @@ -424,7 +424,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | ||
424 | fprintf(stderr, "qemu: got signal %d\n", sig); | 424 | fprintf(stderr, "qemu: got signal %d\n", sig); |
425 | #endif | 425 | #endif |
426 | host_to_target_siginfo_noswap(&tinfo, info); | 426 | host_to_target_siginfo_noswap(&tinfo, info); |
427 | - if (queue_signal(sig, &tinfo) == 1) { | 427 | + if (queue_signal(global_env, sig, &tinfo) == 1) { |
428 | /* interrupt the virtual CPU as soon as possible */ | 428 | /* interrupt the virtual CPU as soon as possible */ |
429 | cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); | 429 | cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); |
430 | } | 430 | } |
@@ -496,7 +496,7 @@ out: | @@ -496,7 +496,7 @@ out: | ||
496 | int do_sigaction(int sig, const struct target_sigaction *act, | 496 | int do_sigaction(int sig, const struct target_sigaction *act, |
497 | struct target_sigaction *oact) | 497 | struct target_sigaction *oact) |
498 | { | 498 | { |
499 | - struct emulated_sigaction *k; | 499 | + struct target_sigaction *k; |
500 | struct sigaction act1; | 500 | struct sigaction act1; |
501 | int host_sig; | 501 | int host_sig; |
502 | int ret = 0; | 502 | int ret = 0; |
@@ -509,34 +509,35 @@ int do_sigaction(int sig, const struct target_sigaction *act, | @@ -509,34 +509,35 @@ int do_sigaction(int sig, const struct target_sigaction *act, | ||
509 | sig, (int)act, (int)oact); | 509 | sig, (int)act, (int)oact); |
510 | #endif | 510 | #endif |
511 | if (oact) { | 511 | if (oact) { |
512 | - oact->_sa_handler = tswapl(k->sa._sa_handler); | ||
513 | - oact->sa_flags = tswapl(k->sa.sa_flags); | 512 | + oact->_sa_handler = tswapl(k->_sa_handler); |
513 | + oact->sa_flags = tswapl(k->sa_flags); | ||
514 | #if !defined(TARGET_MIPS) | 514 | #if !defined(TARGET_MIPS) |
515 | - oact->sa_restorer = tswapl(k->sa.sa_restorer); | 515 | + oact->sa_restorer = tswapl(k->sa_restorer); |
516 | #endif | 516 | #endif |
517 | - oact->sa_mask = k->sa.sa_mask; | 517 | + oact->sa_mask = k->sa_mask; |
518 | } | 518 | } |
519 | if (act) { | 519 | if (act) { |
520 | - k->sa._sa_handler = tswapl(act->_sa_handler); | ||
521 | - k->sa.sa_flags = tswapl(act->sa_flags); | 520 | + /* FIXME: This is not threadsafe. */ |
521 | + k->_sa_handler = tswapl(act->_sa_handler); | ||
522 | + k->sa_flags = tswapl(act->sa_flags); | ||
522 | #if !defined(TARGET_MIPS) | 523 | #if !defined(TARGET_MIPS) |
523 | - k->sa.sa_restorer = tswapl(act->sa_restorer); | 524 | + k->sa_restorer = tswapl(act->sa_restorer); |
524 | #endif | 525 | #endif |
525 | - k->sa.sa_mask = act->sa_mask; | 526 | + k->sa_mask = act->sa_mask; |
526 | 527 | ||
527 | /* we update the host linux signal state */ | 528 | /* we update the host linux signal state */ |
528 | host_sig = target_to_host_signal(sig); | 529 | host_sig = target_to_host_signal(sig); |
529 | if (host_sig != SIGSEGV && host_sig != SIGBUS) { | 530 | if (host_sig != SIGSEGV && host_sig != SIGBUS) { |
530 | sigfillset(&act1.sa_mask); | 531 | sigfillset(&act1.sa_mask); |
531 | act1.sa_flags = SA_SIGINFO; | 532 | act1.sa_flags = SA_SIGINFO; |
532 | - if (k->sa.sa_flags & TARGET_SA_RESTART) | 533 | + if (k->sa_flags & TARGET_SA_RESTART) |
533 | act1.sa_flags |= SA_RESTART; | 534 | act1.sa_flags |= SA_RESTART; |
534 | /* NOTE: it is important to update the host kernel signal | 535 | /* NOTE: it is important to update the host kernel signal |
535 | ignore state to avoid getting unexpected interrupted | 536 | ignore state to avoid getting unexpected interrupted |
536 | syscalls */ | 537 | syscalls */ |
537 | - if (k->sa._sa_handler == TARGET_SIG_IGN) { | 538 | + if (k->_sa_handler == TARGET_SIG_IGN) { |
538 | act1.sa_sigaction = (void *)SIG_IGN; | 539 | act1.sa_sigaction = (void *)SIG_IGN; |
539 | - } else if (k->sa._sa_handler == TARGET_SIG_DFL) { | 540 | + } else if (k->_sa_handler == TARGET_SIG_DFL) { |
540 | act1.sa_sigaction = (void *)SIG_DFL; | 541 | act1.sa_sigaction = (void *)SIG_DFL; |
541 | } else { | 542 | } else { |
542 | act1.sa_sigaction = host_signal_handler; | 543 | act1.sa_sigaction = host_signal_handler; |
@@ -712,14 +713,14 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, | @@ -712,14 +713,14 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate, | ||
712 | */ | 713 | */ |
713 | 714 | ||
714 | static inline abi_ulong | 715 | static inline abi_ulong |
715 | -get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) | 716 | +get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size) |
716 | { | 717 | { |
717 | unsigned long esp; | 718 | unsigned long esp; |
718 | 719 | ||
719 | /* Default to using normal stack */ | 720 | /* Default to using normal stack */ |
720 | esp = env->regs[R_ESP]; | 721 | esp = env->regs[R_ESP]; |
721 | /* This is the X/Open sanctioned signal stack switching. */ | 722 | /* This is the X/Open sanctioned signal stack switching. */ |
722 | - if (ka->sa.sa_flags & TARGET_SA_ONSTACK) { | 723 | + if (ka->sa_flags & TARGET_SA_ONSTACK) { |
723 | if (sas_ss_flags(esp) == 0) | 724 | if (sas_ss_flags(esp) == 0) |
724 | esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | 725 | esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; |
725 | } | 726 | } |
@@ -727,15 +728,15 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) | @@ -727,15 +728,15 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size) | ||
727 | /* This is the legacy signal stack switching. */ | 728 | /* This is the legacy signal stack switching. */ |
728 | else | 729 | else |
729 | if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && | 730 | if ((env->segs[R_SS].selector & 0xffff) != __USER_DS && |
730 | - !(ka->sa.sa_flags & TARGET_SA_RESTORER) && | ||
731 | - ka->sa.sa_restorer) { | ||
732 | - esp = (unsigned long) ka->sa.sa_restorer; | 731 | + !(ka->sa_flags & TARGET_SA_RESTORER) && |
732 | + ka->sa_restorer) { | ||
733 | + esp = (unsigned long) ka->sa_restorer; | ||
733 | } | 734 | } |
734 | return (esp - frame_size) & -8ul; | 735 | return (esp - frame_size) & -8ul; |
735 | } | 736 | } |
736 | 737 | ||
737 | /* compare linux/arch/i386/kernel/signal.c:setup_frame() */ | 738 | /* compare linux/arch/i386/kernel/signal.c:setup_frame() */ |
738 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 739 | +static void setup_frame(int sig, struct target_sigaction *ka, |
739 | target_sigset_t *set, CPUX86State *env) | 740 | target_sigset_t *set, CPUX86State *env) |
740 | { | 741 | { |
741 | abi_ulong frame_addr; | 742 | abi_ulong frame_addr; |
@@ -764,8 +765,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -764,8 +765,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
764 | 765 | ||
765 | /* Set up to return from userspace. If provided, use a stub | 766 | /* Set up to return from userspace. If provided, use a stub |
766 | already in userspace. */ | 767 | already in userspace. */ |
767 | - if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | ||
768 | - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); | 768 | + if (ka->sa_flags & TARGET_SA_RESTORER) { |
769 | + err |= __put_user(ka->sa_restorer, &frame->pretcode); | ||
769 | } else { | 770 | } else { |
770 | uint16_t val16; | 771 | uint16_t val16; |
771 | abi_ulong retcode_addr; | 772 | abi_ulong retcode_addr; |
@@ -784,7 +785,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -784,7 +785,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
784 | 785 | ||
785 | /* Set up registers for signal handler */ | 786 | /* Set up registers for signal handler */ |
786 | env->regs[R_ESP] = frame_addr; | 787 | env->regs[R_ESP] = frame_addr; |
787 | - env->eip = ka->sa._sa_handler; | 788 | + env->eip = ka->_sa_handler; |
788 | 789 | ||
789 | cpu_x86_load_seg(env, R_DS, __USER_DS); | 790 | cpu_x86_load_seg(env, R_DS, __USER_DS); |
790 | cpu_x86_load_seg(env, R_ES, __USER_DS); | 791 | cpu_x86_load_seg(env, R_ES, __USER_DS); |
@@ -799,12 +800,12 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -799,12 +800,12 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
799 | give_sigsegv: | 800 | give_sigsegv: |
800 | unlock_user_struct(frame, frame_addr, 1); | 801 | unlock_user_struct(frame, frame_addr, 1); |
801 | if (sig == TARGET_SIGSEGV) | 802 | if (sig == TARGET_SIGSEGV) |
802 | - ka->sa._sa_handler = TARGET_SIG_DFL; | 803 | + ka->_sa_handler = TARGET_SIG_DFL; |
803 | force_sig(TARGET_SIGSEGV /* , current */); | 804 | force_sig(TARGET_SIGSEGV /* , current */); |
804 | } | 805 | } |
805 | 806 | ||
806 | /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */ | 807 | /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */ |
807 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 808 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
808 | target_siginfo_t *info, | 809 | target_siginfo_t *info, |
809 | target_sigset_t *set, CPUX86State *env) | 810 | target_sigset_t *set, CPUX86State *env) |
810 | { | 811 | { |
@@ -846,8 +847,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -846,8 +847,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
846 | 847 | ||
847 | /* Set up to return from userspace. If provided, use a stub | 848 | /* Set up to return from userspace. If provided, use a stub |
848 | already in userspace. */ | 849 | already in userspace. */ |
849 | - if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | ||
850 | - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); | 850 | + if (ka->sa_flags & TARGET_SA_RESTORER) { |
851 | + err |= __put_user(ka->sa_restorer, &frame->pretcode); | ||
851 | } else { | 852 | } else { |
852 | uint16_t val16; | 853 | uint16_t val16; |
853 | addr = frame_addr + offsetof(struct rt_sigframe, retcode); | 854 | addr = frame_addr + offsetof(struct rt_sigframe, retcode); |
@@ -864,7 +865,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -864,7 +865,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
864 | 865 | ||
865 | /* Set up registers for signal handler */ | 866 | /* Set up registers for signal handler */ |
866 | env->regs[R_ESP] = frame_addr; | 867 | env->regs[R_ESP] = frame_addr; |
867 | - env->eip = ka->sa._sa_handler; | 868 | + env->eip = ka->_sa_handler; |
868 | 869 | ||
869 | cpu_x86_load_seg(env, R_DS, __USER_DS); | 870 | cpu_x86_load_seg(env, R_DS, __USER_DS); |
870 | cpu_x86_load_seg(env, R_ES, __USER_DS); | 871 | cpu_x86_load_seg(env, R_ES, __USER_DS); |
@@ -879,7 +880,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -879,7 +880,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
879 | give_sigsegv: | 880 | give_sigsegv: |
880 | unlock_user_struct(frame, frame_addr, 1); | 881 | unlock_user_struct(frame, frame_addr, 1); |
881 | if (sig == TARGET_SIGSEGV) | 882 | if (sig == TARGET_SIGSEGV) |
882 | - ka->sa._sa_handler = TARGET_SIG_DFL; | 883 | + ka->_sa_handler = TARGET_SIG_DFL; |
883 | force_sig(TARGET_SIGSEGV /* , current */); | 884 | force_sig(TARGET_SIGSEGV /* , current */); |
884 | } | 885 | } |
885 | 886 | ||
@@ -1122,14 +1123,14 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ | @@ -1122,14 +1123,14 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ | ||
1122 | } | 1123 | } |
1123 | 1124 | ||
1124 | static inline abi_ulong | 1125 | static inline abi_ulong |
1125 | -get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) | 1126 | +get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize) |
1126 | { | 1127 | { |
1127 | unsigned long sp = regs->regs[13]; | 1128 | unsigned long sp = regs->regs[13]; |
1128 | 1129 | ||
1129 | /* | 1130 | /* |
1130 | * This is the X/Open sanctioned signal stack switching. | 1131 | * This is the X/Open sanctioned signal stack switching. |
1131 | */ | 1132 | */ |
1132 | - if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) | 1133 | + if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) |
1133 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | 1134 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; |
1134 | /* | 1135 | /* |
1135 | * ATPCS B01 mandates 8-byte alignment | 1136 | * ATPCS B01 mandates 8-byte alignment |
@@ -1138,19 +1139,19 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) | @@ -1138,19 +1139,19 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) | ||
1138 | } | 1139 | } |
1139 | 1140 | ||
1140 | static int | 1141 | static int |
1141 | -setup_return(CPUState *env, struct emulated_sigaction *ka, | 1142 | +setup_return(CPUState *env, struct target_sigaction *ka, |
1142 | abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr) | 1143 | abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr) |
1143 | { | 1144 | { |
1144 | - abi_ulong handler = ka->sa._sa_handler; | 1145 | + abi_ulong handler = ka->_sa_handler; |
1145 | abi_ulong retcode; | 1146 | abi_ulong retcode; |
1146 | int thumb = handler & 1; | 1147 | int thumb = handler & 1; |
1147 | 1148 | ||
1148 | - if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | ||
1149 | - retcode = ka->sa.sa_restorer; | 1149 | + if (ka->sa_flags & TARGET_SA_RESTORER) { |
1150 | + retcode = ka->sa_restorer; | ||
1150 | } else { | 1151 | } else { |
1151 | unsigned int idx = thumb; | 1152 | unsigned int idx = thumb; |
1152 | 1153 | ||
1153 | - if (ka->sa.sa_flags & TARGET_SA_SIGINFO) | 1154 | + if (ka->sa_flags & TARGET_SA_SIGINFO) |
1154 | idx += 2; | 1155 | idx += 2; |
1155 | 1156 | ||
1156 | if (__put_user(retcodes[idx], rc)) | 1157 | if (__put_user(retcodes[idx], rc)) |
@@ -1200,7 +1201,7 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc, | @@ -1200,7 +1201,7 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc, | ||
1200 | } | 1201 | } |
1201 | 1202 | ||
1202 | /* compare linux/arch/arm/kernel/signal.c:setup_frame() */ | 1203 | /* compare linux/arch/arm/kernel/signal.c:setup_frame() */ |
1203 | -static void setup_frame_v1(int usig, struct emulated_sigaction *ka, | 1204 | +static void setup_frame_v1(int usig, struct target_sigaction *ka, |
1204 | target_sigset_t *set, CPUState *regs) | 1205 | target_sigset_t *set, CPUState *regs) |
1205 | { | 1206 | { |
1206 | struct sigframe_v1 *frame; | 1207 | struct sigframe_v1 *frame; |
@@ -1224,7 +1225,7 @@ end: | @@ -1224,7 +1225,7 @@ end: | ||
1224 | unlock_user_struct(frame, frame_addr, 1); | 1225 | unlock_user_struct(frame, frame_addr, 1); |
1225 | } | 1226 | } |
1226 | 1227 | ||
1227 | -static void setup_frame_v2(int usig, struct emulated_sigaction *ka, | 1228 | +static void setup_frame_v2(int usig, struct target_sigaction *ka, |
1228 | target_sigset_t *set, CPUState *regs) | 1229 | target_sigset_t *set, CPUState *regs) |
1229 | { | 1230 | { |
1230 | struct sigframe_v2 *frame; | 1231 | struct sigframe_v2 *frame; |
@@ -1241,7 +1242,7 @@ static void setup_frame_v2(int usig, struct emulated_sigaction *ka, | @@ -1241,7 +1242,7 @@ static void setup_frame_v2(int usig, struct emulated_sigaction *ka, | ||
1241 | unlock_user_struct(frame, frame_addr, 1); | 1242 | unlock_user_struct(frame, frame_addr, 1); |
1242 | } | 1243 | } |
1243 | 1244 | ||
1244 | -static void setup_frame(int usig, struct emulated_sigaction *ka, | 1245 | +static void setup_frame(int usig, struct target_sigaction *ka, |
1245 | target_sigset_t *set, CPUState *regs) | 1246 | target_sigset_t *set, CPUState *regs) |
1246 | { | 1247 | { |
1247 | if (get_osversion() >= 0x020612) { | 1248 | if (get_osversion() >= 0x020612) { |
@@ -1252,7 +1253,7 @@ static void setup_frame(int usig, struct emulated_sigaction *ka, | @@ -1252,7 +1253,7 @@ static void setup_frame(int usig, struct emulated_sigaction *ka, | ||
1252 | } | 1253 | } |
1253 | 1254 | ||
1254 | /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */ | 1255 | /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */ |
1255 | -static void setup_rt_frame_v1(int usig, struct emulated_sigaction *ka, | 1256 | +static void setup_rt_frame_v1(int usig, struct target_sigaction *ka, |
1256 | target_siginfo_t *info, | 1257 | target_siginfo_t *info, |
1257 | target_sigset_t *set, CPUState *env) | 1258 | target_sigset_t *set, CPUState *env) |
1258 | { | 1259 | { |
@@ -1296,7 +1297,7 @@ end: | @@ -1296,7 +1297,7 @@ end: | ||
1296 | unlock_user_struct(frame, frame_addr, 1); | 1297 | unlock_user_struct(frame, frame_addr, 1); |
1297 | } | 1298 | } |
1298 | 1299 | ||
1299 | -static void setup_rt_frame_v2(int usig, struct emulated_sigaction *ka, | 1300 | +static void setup_rt_frame_v2(int usig, struct target_sigaction *ka, |
1300 | target_siginfo_t *info, | 1301 | target_siginfo_t *info, |
1301 | target_sigset_t *set, CPUState *env) | 1302 | target_sigset_t *set, CPUState *env) |
1302 | { | 1303 | { |
@@ -1322,7 +1323,7 @@ static void setup_rt_frame_v2(int usig, struct emulated_sigaction *ka, | @@ -1322,7 +1323,7 @@ static void setup_rt_frame_v2(int usig, struct emulated_sigaction *ka, | ||
1322 | unlock_user_struct(frame, frame_addr, 1); | 1323 | unlock_user_struct(frame, frame_addr, 1); |
1323 | } | 1324 | } |
1324 | 1325 | ||
1325 | -static void setup_rt_frame(int usig, struct emulated_sigaction *ka, | 1326 | +static void setup_rt_frame(int usig, struct target_sigaction *ka, |
1326 | target_siginfo_t *info, | 1327 | target_siginfo_t *info, |
1327 | target_sigset_t *set, CPUState *env) | 1328 | target_sigset_t *set, CPUState *env) |
1328 | { | 1329 | { |
@@ -1650,7 +1651,7 @@ struct target_rt_signal_frame { | @@ -1650,7 +1651,7 @@ struct target_rt_signal_frame { | ||
1650 | #define UREG_FP UREG_I6 | 1651 | #define UREG_FP UREG_I6 |
1651 | #define UREG_SP UREG_O6 | 1652 | #define UREG_SP UREG_O6 |
1652 | 1653 | ||
1653 | -static inline abi_ulong get_sigframe(struct emulated_sigaction *sa, | 1654 | +static inline abi_ulong get_sigframe(struct target_sigaction *sa, |
1654 | CPUState *env, unsigned long framesize) | 1655 | CPUState *env, unsigned long framesize) |
1655 | { | 1656 | { |
1656 | abi_ulong sp; | 1657 | abi_ulong sp; |
@@ -1658,7 +1659,7 @@ static inline abi_ulong get_sigframe(struct emulated_sigaction *sa, | @@ -1658,7 +1659,7 @@ static inline abi_ulong get_sigframe(struct emulated_sigaction *sa, | ||
1658 | sp = env->regwptr[UREG_FP]; | 1659 | sp = env->regwptr[UREG_FP]; |
1659 | 1660 | ||
1660 | /* This is the X/Open sanctioned signal stack switching. */ | 1661 | /* This is the X/Open sanctioned signal stack switching. */ |
1661 | - if (sa->sa.sa_flags & TARGET_SA_ONSTACK) { | 1662 | + if (sa->sa_flags & TARGET_SA_ONSTACK) { |
1662 | if (!on_sig_stack(sp) | 1663 | if (!on_sig_stack(sp) |
1663 | && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) | 1664 | && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) |
1664 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | 1665 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; |
@@ -1705,7 +1706,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ | @@ -1705,7 +1706,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ | ||
1705 | #endif | 1706 | #endif |
1706 | #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7))) | 1707 | #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7))) |
1707 | 1708 | ||
1708 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 1709 | +static void setup_frame(int sig, struct target_sigaction *ka, |
1709 | target_sigset_t *set, CPUState *env) | 1710 | target_sigset_t *set, CPUState *env) |
1710 | { | 1711 | { |
1711 | abi_ulong sf_addr; | 1712 | abi_ulong sf_addr; |
@@ -1758,11 +1759,11 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -1758,11 +1759,11 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
1758 | offsetof(struct target_signal_frame, info); | 1759 | offsetof(struct target_signal_frame, info); |
1759 | 1760 | ||
1760 | /* 4. signal handler */ | 1761 | /* 4. signal handler */ |
1761 | - env->pc = ka->sa._sa_handler; | 1762 | + env->pc = ka->_sa_handler; |
1762 | env->npc = (env->pc + 4); | 1763 | env->npc = (env->pc + 4); |
1763 | /* 5. return to kernel instructions */ | 1764 | /* 5. return to kernel instructions */ |
1764 | - if (ka->sa.sa_restorer) | ||
1765 | - env->regwptr[UREG_I7] = ka->sa.sa_restorer; | 1765 | + if (ka->sa_restorer) |
1766 | + env->regwptr[UREG_I7] = ka->sa_restorer; | ||
1766 | else { | 1767 | else { |
1767 | uint32_t val32; | 1768 | uint32_t val32; |
1768 | 1769 | ||
@@ -1834,7 +1835,7 @@ restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu) | @@ -1834,7 +1835,7 @@ restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu) | ||
1834 | } | 1835 | } |
1835 | 1836 | ||
1836 | 1837 | ||
1837 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 1838 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
1838 | target_siginfo_t *info, | 1839 | target_siginfo_t *info, |
1839 | target_sigset_t *set, CPUState *env) | 1840 | target_sigset_t *set, CPUState *env) |
1840 | { | 1841 | { |
@@ -2182,13 +2183,13 @@ void sparc64_get_context(CPUSPARCState *env) | @@ -2182,13 +2183,13 @@ void sparc64_get_context(CPUSPARCState *env) | ||
2182 | 2183 | ||
2183 | # warning signal handling not implemented | 2184 | # warning signal handling not implemented |
2184 | 2185 | ||
2185 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 2186 | +static void setup_frame(int sig, struct target_sigaction *ka, |
2186 | target_sigset_t *set, CPUState *env) | 2187 | target_sigset_t *set, CPUState *env) |
2187 | { | 2188 | { |
2188 | fprintf(stderr, "setup_frame: not implemented\n"); | 2189 | fprintf(stderr, "setup_frame: not implemented\n"); |
2189 | } | 2190 | } |
2190 | 2191 | ||
2191 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 2192 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
2192 | target_siginfo_t *info, | 2193 | target_siginfo_t *info, |
2193 | target_sigset_t *set, CPUState *env) | 2194 | target_sigset_t *set, CPUState *env) |
2194 | { | 2195 | { |
@@ -2211,13 +2212,13 @@ long do_rt_sigreturn(CPUState *env) | @@ -2211,13 +2212,13 @@ long do_rt_sigreturn(CPUState *env) | ||
2211 | 2212 | ||
2212 | # warning signal handling not implemented | 2213 | # warning signal handling not implemented |
2213 | 2214 | ||
2214 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 2215 | +static void setup_frame(int sig, struct target_sigaction *ka, |
2215 | target_sigset_t *set, CPUState *env) | 2216 | target_sigset_t *set, CPUState *env) |
2216 | { | 2217 | { |
2217 | fprintf(stderr, "setup_frame: not implemented\n"); | 2218 | fprintf(stderr, "setup_frame: not implemented\n"); |
2218 | } | 2219 | } |
2219 | 2220 | ||
2220 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 2221 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
2221 | target_siginfo_t *info, | 2222 | target_siginfo_t *info, |
2222 | target_sigset_t *set, CPUState *env) | 2223 | target_sigset_t *set, CPUState *env) |
2223 | { | 2224 | { |
@@ -2431,7 +2432,7 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc) | @@ -2431,7 +2432,7 @@ restore_sigcontext(CPUState *regs, struct target_sigcontext *sc) | ||
2431 | * Determine which stack to use.. | 2432 | * Determine which stack to use.. |
2432 | */ | 2433 | */ |
2433 | static inline abi_ulong | 2434 | static inline abi_ulong |
2434 | -get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | 2435 | +get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size) |
2435 | { | 2436 | { |
2436 | unsigned long sp; | 2437 | unsigned long sp; |
2437 | 2438 | ||
@@ -2446,7 +2447,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | @@ -2446,7 +2447,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | ||
2446 | sp -= 32; | 2447 | sp -= 32; |
2447 | 2448 | ||
2448 | /* This is the X/Open sanctioned signal stack switching. */ | 2449 | /* This is the X/Open sanctioned signal stack switching. */ |
2449 | - if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) { | 2450 | + if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) { |
2450 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | 2451 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; |
2451 | } | 2452 | } |
2452 | 2453 | ||
@@ -2454,7 +2455,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | @@ -2454,7 +2455,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, size_t frame_size) | ||
2454 | } | 2455 | } |
2455 | 2456 | ||
2456 | /* compare linux/arch/mips/kernel/signal.c:setup_frame() */ | 2457 | /* compare linux/arch/mips/kernel/signal.c:setup_frame() */ |
2457 | -static void setup_frame(int sig, struct emulated_sigaction * ka, | 2458 | +static void setup_frame(int sig, struct target_sigaction * ka, |
2458 | target_sigset_t *set, CPUState *regs) | 2459 | target_sigset_t *set, CPUState *regs) |
2459 | { | 2460 | { |
2460 | struct sigframe *frame; | 2461 | struct sigframe *frame; |
@@ -2493,7 +2494,7 @@ static void setup_frame(int sig, struct emulated_sigaction * ka, | @@ -2493,7 +2494,7 @@ static void setup_frame(int sig, struct emulated_sigaction * ka, | ||
2493 | /* The original kernel code sets CP0_EPC to the handler | 2494 | /* The original kernel code sets CP0_EPC to the handler |
2494 | * since it returns to userland using eret | 2495 | * since it returns to userland using eret |
2495 | * we cannot do this here, and we must set PC directly */ | 2496 | * we cannot do this here, and we must set PC directly */ |
2496 | - regs->PC[regs->current_tc] = regs->gpr[regs->current_tc][25] = ka->sa._sa_handler; | 2497 | + regs->PC[regs->current_tc] = regs->gpr[regs->current_tc][25] = ka->_sa_handler; |
2497 | unlock_user_struct(frame, frame_addr, 1); | 2498 | unlock_user_struct(frame, frame_addr, 1); |
2498 | return; | 2499 | return; |
2499 | 2500 | ||
@@ -2552,7 +2553,7 @@ badframe: | @@ -2552,7 +2553,7 @@ badframe: | ||
2552 | return 0; | 2553 | return 0; |
2553 | } | 2554 | } |
2554 | 2555 | ||
2555 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 2556 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
2556 | target_siginfo_t *info, | 2557 | target_siginfo_t *info, |
2557 | target_sigset_t *set, CPUState *env) | 2558 | target_sigset_t *set, CPUState *env) |
2558 | { | 2559 | { |
@@ -2620,10 +2621,10 @@ struct target_rt_sigframe | @@ -2620,10 +2621,10 @@ struct target_rt_sigframe | ||
2620 | #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ | 2621 | #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ |
2621 | #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */ | 2622 | #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */ |
2622 | 2623 | ||
2623 | -static abi_ulong get_sigframe(struct emulated_sigaction *ka, | 2624 | +static abi_ulong get_sigframe(struct target_sigaction *ka, |
2624 | unsigned long sp, size_t frame_size) | 2625 | unsigned long sp, size_t frame_size) |
2625 | { | 2626 | { |
2626 | - if ((ka->sa.sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { | 2627 | + if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { |
2627 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; | 2628 | sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; |
2628 | } | 2629 | } |
2629 | 2630 | ||
@@ -2682,7 +2683,7 @@ static int restore_sigcontext(struct CPUState *regs, | @@ -2682,7 +2683,7 @@ static int restore_sigcontext(struct CPUState *regs, | ||
2682 | return err; | 2683 | return err; |
2683 | } | 2684 | } |
2684 | 2685 | ||
2685 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 2686 | +static void setup_frame(int sig, struct target_sigaction *ka, |
2686 | target_sigset_t *set, CPUState *regs) | 2687 | target_sigset_t *set, CPUState *regs) |
2687 | { | 2688 | { |
2688 | struct target_sigframe *frame; | 2689 | struct target_sigframe *frame; |
@@ -2705,8 +2706,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -2705,8 +2706,8 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
2705 | 2706 | ||
2706 | /* Set up to return from userspace. If provided, use a stub | 2707 | /* Set up to return from userspace. If provided, use a stub |
2707 | already in userspace. */ | 2708 | already in userspace. */ |
2708 | - if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | ||
2709 | - regs->pr = (unsigned long) ka->sa.sa_restorer; | 2709 | + if (ka->sa_flags & TARGET_SA_RESTORER) { |
2710 | + regs->pr = (unsigned long) ka->sa_restorer; | ||
2710 | } else { | 2711 | } else { |
2711 | /* Generate return code (system call to sigreturn) */ | 2712 | /* Generate return code (system call to sigreturn) */ |
2712 | err |= __put_user(MOVW(2), &frame->retcode[0]); | 2713 | err |= __put_user(MOVW(2), &frame->retcode[0]); |
@@ -2723,7 +2724,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -2723,7 +2724,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
2723 | regs->gregs[4] = signal; /* Arg for signal handler */ | 2724 | regs->gregs[4] = signal; /* Arg for signal handler */ |
2724 | regs->gregs[5] = 0; | 2725 | regs->gregs[5] = 0; |
2725 | regs->gregs[6] = (unsigned long) &frame->sc; | 2726 | regs->gregs[6] = (unsigned long) &frame->sc; |
2726 | - regs->pc = (unsigned long) ka->sa._sa_handler; | 2727 | + regs->pc = (unsigned long) ka->_sa_handler; |
2727 | 2728 | ||
2728 | unlock_user_struct(frame, frame_addr, 1); | 2729 | unlock_user_struct(frame, frame_addr, 1); |
2729 | return; | 2730 | return; |
@@ -2733,7 +2734,7 @@ give_sigsegv: | @@ -2733,7 +2734,7 @@ give_sigsegv: | ||
2733 | force_sig(SIGSEGV); | 2734 | force_sig(SIGSEGV); |
2734 | } | 2735 | } |
2735 | 2736 | ||
2736 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 2737 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
2737 | target_siginfo_t *info, | 2738 | target_siginfo_t *info, |
2738 | target_sigset_t *set, CPUState *regs) | 2739 | target_sigset_t *set, CPUState *regs) |
2739 | { | 2740 | { |
@@ -2768,8 +2769,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -2768,8 +2769,8 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
2768 | 2769 | ||
2769 | /* Set up to return from userspace. If provided, use a stub | 2770 | /* Set up to return from userspace. If provided, use a stub |
2770 | already in userspace. */ | 2771 | already in userspace. */ |
2771 | - if (ka->sa.sa_flags & TARGET_SA_RESTORER) { | ||
2772 | - regs->pr = (unsigned long) ka->sa.sa_restorer; | 2772 | + if (ka->sa_flags & TARGET_SA_RESTORER) { |
2773 | + regs->pr = (unsigned long) ka->sa_restorer; | ||
2773 | } else { | 2774 | } else { |
2774 | /* Generate return code (system call to sigreturn) */ | 2775 | /* Generate return code (system call to sigreturn) */ |
2775 | err |= __put_user(MOVW(2), &frame->retcode[0]); | 2776 | err |= __put_user(MOVW(2), &frame->retcode[0]); |
@@ -2786,7 +2787,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | @@ -2786,7 +2787,7 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | ||
2786 | regs->gregs[4] = signal; /* Arg for signal handler */ | 2787 | regs->gregs[4] = signal; /* Arg for signal handler */ |
2787 | regs->gregs[5] = (unsigned long) &frame->info; | 2788 | regs->gregs[5] = (unsigned long) &frame->info; |
2788 | regs->gregs[6] = (unsigned long) &frame->uc; | 2789 | regs->gregs[6] = (unsigned long) &frame->uc; |
2789 | - regs->pc = (unsigned long) ka->sa._sa_handler; | 2790 | + regs->pc = (unsigned long) ka->_sa_handler; |
2790 | 2791 | ||
2791 | unlock_user_struct(frame, frame_addr, 1); | 2792 | unlock_user_struct(frame, frame_addr, 1); |
2792 | return; | 2793 | return; |
@@ -2944,7 +2945,7 @@ static abi_ulong get_sigframe(CPUState *env, int framesize) | @@ -2944,7 +2945,7 @@ static abi_ulong get_sigframe(CPUState *env, int framesize) | ||
2944 | return sp - framesize; | 2945 | return sp - framesize; |
2945 | } | 2946 | } |
2946 | 2947 | ||
2947 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 2948 | +static void setup_frame(int sig, struct target_sigaction *ka, |
2948 | target_sigset_t *set, CPUState *env) | 2949 | target_sigset_t *set, CPUState *env) |
2949 | { | 2950 | { |
2950 | struct target_signal_frame *frame; | 2951 | struct target_signal_frame *frame; |
@@ -2983,7 +2984,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -2983,7 +2984,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
2983 | /* Move the stack and setup the arguments for the handler. */ | 2984 | /* Move the stack and setup the arguments for the handler. */ |
2984 | env->regs[R_SP] = (uint32_t) frame; | 2985 | env->regs[R_SP] = (uint32_t) frame; |
2985 | env->regs[10] = sig; | 2986 | env->regs[10] = sig; |
2986 | - env->pc = (unsigned long) ka->sa._sa_handler; | 2987 | + env->pc = (unsigned long) ka->_sa_handler; |
2987 | /* Link SRP so the guest returns through the trampoline. */ | 2988 | /* Link SRP so the guest returns through the trampoline. */ |
2988 | env->pregs[PR_SRP] = (uint32_t) &frame->retcode[0]; | 2989 | env->pregs[PR_SRP] = (uint32_t) &frame->retcode[0]; |
2989 | 2990 | ||
@@ -2994,7 +2995,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | @@ -2994,7 +2995,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, | ||
2994 | force_sig(TARGET_SIGSEGV); | 2995 | force_sig(TARGET_SIGSEGV); |
2995 | } | 2996 | } |
2996 | 2997 | ||
2997 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 2998 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
2998 | target_siginfo_t *info, | 2999 | target_siginfo_t *info, |
2999 | target_sigset_t *set, CPUState *env) | 3000 | target_sigset_t *set, CPUState *env) |
3000 | { | 3001 | { |
@@ -3043,13 +3044,13 @@ long do_rt_sigreturn(CPUState *env) | @@ -3043,13 +3044,13 @@ long do_rt_sigreturn(CPUState *env) | ||
3043 | 3044 | ||
3044 | #else | 3045 | #else |
3045 | 3046 | ||
3046 | -static void setup_frame(int sig, struct emulated_sigaction *ka, | 3047 | +static void setup_frame(int sig, struct target_sigaction *ka, |
3047 | target_sigset_t *set, CPUState *env) | 3048 | target_sigset_t *set, CPUState *env) |
3048 | { | 3049 | { |
3049 | fprintf(stderr, "setup_frame: not implemented\n"); | 3050 | fprintf(stderr, "setup_frame: not implemented\n"); |
3050 | } | 3051 | } |
3051 | 3052 | ||
3052 | -static void setup_rt_frame(int sig, struct emulated_sigaction *ka, | 3053 | +static void setup_rt_frame(int sig, struct target_sigaction *ka, |
3053 | target_siginfo_t *info, | 3054 | target_siginfo_t *info, |
3054 | target_sigset_t *set, CPUState *env) | 3055 | target_sigset_t *set, CPUState *env) |
3055 | { | 3056 | { |
@@ -3070,26 +3071,29 @@ long do_rt_sigreturn(CPUState *env) | @@ -3070,26 +3071,29 @@ long do_rt_sigreturn(CPUState *env) | ||
3070 | 3071 | ||
3071 | #endif | 3072 | #endif |
3072 | 3073 | ||
3073 | -void process_pending_signals(void *cpu_env) | 3074 | +void process_pending_signals(CPUState *cpu_env) |
3074 | { | 3075 | { |
3075 | int sig; | 3076 | int sig; |
3076 | abi_ulong handler; | 3077 | abi_ulong handler; |
3077 | sigset_t set, old_set; | 3078 | sigset_t set, old_set; |
3078 | target_sigset_t target_old_set; | 3079 | target_sigset_t target_old_set; |
3079 | - struct emulated_sigaction *k; | 3080 | + struct emulated_sigtable *k; |
3081 | + struct target_sigaction *sa; | ||
3080 | struct sigqueue *q; | 3082 | struct sigqueue *q; |
3083 | + TaskState *ts = cpu_env->opaque; | ||
3081 | 3084 | ||
3082 | - if (!signal_pending) | 3085 | + if (!ts->signal_pending) |
3083 | return; | 3086 | return; |
3084 | 3087 | ||
3085 | - k = sigact_table; | 3088 | + /* FIXME: This is not threadsafe. */ |
3089 | + k = ts->sigtab; | ||
3086 | for(sig = 1; sig <= TARGET_NSIG; sig++) { | 3090 | for(sig = 1; sig <= TARGET_NSIG; sig++) { |
3087 | if (k->pending) | 3091 | if (k->pending) |
3088 | goto handle_signal; | 3092 | goto handle_signal; |
3089 | k++; | 3093 | k++; |
3090 | } | 3094 | } |
3091 | /* if no signal is pending, just return */ | 3095 | /* if no signal is pending, just return */ |
3092 | - signal_pending = 0; | 3096 | + ts->signal_pending = 0; |
3093 | return; | 3097 | return; |
3094 | 3098 | ||
3095 | handle_signal: | 3099 | handle_signal: |
@@ -3108,7 +3112,8 @@ void process_pending_signals(void *cpu_env) | @@ -3108,7 +3112,8 @@ void process_pending_signals(void *cpu_env) | ||
3108 | abort(); | 3112 | abort(); |
3109 | } | 3113 | } |
3110 | 3114 | ||
3111 | - handler = k->sa._sa_handler; | 3115 | + sa = &sigact_table[sig - 1]; |
3116 | + handler = sa->_sa_handler; | ||
3112 | if (handler == TARGET_SIG_DFL) { | 3117 | if (handler == TARGET_SIG_DFL) { |
3113 | /* default handler : ignore some signal. The other are fatal */ | 3118 | /* default handler : ignore some signal. The other are fatal */ |
3114 | if (sig != TARGET_SIGCHLD && | 3119 | if (sig != TARGET_SIGCHLD && |
@@ -3122,10 +3127,10 @@ void process_pending_signals(void *cpu_env) | @@ -3122,10 +3127,10 @@ void process_pending_signals(void *cpu_env) | ||
3122 | force_sig(sig); | 3127 | force_sig(sig); |
3123 | } else { | 3128 | } else { |
3124 | /* compute the blocked signals during the handler execution */ | 3129 | /* compute the blocked signals during the handler execution */ |
3125 | - target_to_host_sigset(&set, &k->sa.sa_mask); | 3130 | + target_to_host_sigset(&set, &sa->sa_mask); |
3126 | /* SA_NODEFER indicates that the current signal should not be | 3131 | /* SA_NODEFER indicates that the current signal should not be |
3127 | blocked during the handler */ | 3132 | blocked during the handler */ |
3128 | - if (!(k->sa.sa_flags & TARGET_SA_NODEFER)) | 3133 | + if (!(sa->sa_flags & TARGET_SA_NODEFER)) |
3129 | sigaddset(&set, target_to_host_signal(sig)); | 3134 | sigaddset(&set, target_to_host_signal(sig)); |
3130 | 3135 | ||
3131 | /* block signals in the handler using Linux */ | 3136 | /* block signals in the handler using Linux */ |
@@ -3143,13 +3148,13 @@ void process_pending_signals(void *cpu_env) | @@ -3143,13 +3148,13 @@ void process_pending_signals(void *cpu_env) | ||
3143 | } | 3148 | } |
3144 | #endif | 3149 | #endif |
3145 | /* prepare the stack frame of the virtual CPU */ | 3150 | /* prepare the stack frame of the virtual CPU */ |
3146 | - if (k->sa.sa_flags & TARGET_SA_SIGINFO) | ||
3147 | - setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env); | 3151 | + if (sa->sa_flags & TARGET_SA_SIGINFO) |
3152 | + setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env); | ||
3148 | else | 3153 | else |
3149 | - setup_frame(sig, k, &target_old_set, cpu_env); | ||
3150 | - if (k->sa.sa_flags & TARGET_SA_RESETHAND) | ||
3151 | - k->sa._sa_handler = TARGET_SIG_DFL; | 3154 | + setup_frame(sig, sa, &target_old_set, cpu_env); |
3155 | + if (sa->sa_flags & TARGET_SA_RESETHAND) | ||
3156 | + sa->_sa_handler = TARGET_SIG_DFL; | ||
3152 | } | 3157 | } |
3153 | if (q != &k->info) | 3158 | if (q != &k->info) |
3154 | - free_sigqueue(q); | 3159 | + free_sigqueue(cpu_env, q); |
3155 | } | 3160 | } |
linux-user/syscall.c
@@ -2736,12 +2736,8 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) | @@ -2736,12 +2736,8 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) | ||
2736 | } | 2736 | } |
2737 | #endif | 2737 | #endif |
2738 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); | 2738 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); |
2739 | - memset(ts, 0, sizeof(TaskState)); | 2739 | + init_task_state(ts); |
2740 | new_stack = ts->stack; | 2740 | new_stack = ts->stack; |
2741 | - ts->used = 1; | ||
2742 | - /* add in task state list */ | ||
2743 | - ts->next = first_task_state; | ||
2744 | - first_task_state = ts; | ||
2745 | /* we create a new CPU instance. */ | 2741 | /* we create a new CPU instance. */ |
2746 | new_env = cpu_copy(env); | 2742 | new_env = cpu_copy(env); |
2747 | /* Init regs that differ from the parent. */ | 2743 | /* Init regs that differ from the parent. */ |