Commit 1d9d8b551dba064006f730dbe29a28124dd58418
1 parent
aaf4ad39
Translate signal values in exit status.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7131 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
18 additions
and
2 deletions
linux-user/qemu.h
@@ -201,6 +201,7 @@ int queue_signal(CPUState *env, int sig, target_siginfo_t *info); | @@ -201,6 +201,7 @@ int queue_signal(CPUState *env, int sig, target_siginfo_t *info); | ||
201 | void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | 201 | void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); |
202 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); | 202 | void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); |
203 | int target_to_host_signal(int sig); | 203 | int target_to_host_signal(int sig); |
204 | +int host_to_target_signal(int sig); | ||
204 | long do_sigreturn(CPUState *env); | 205 | long do_sigreturn(CPUState *env); |
205 | long do_rt_sigreturn(CPUState *env); | 206 | long do_rt_sigreturn(CPUState *env); |
206 | abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); | 207 | abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); |
linux-user/signal.c
@@ -102,7 +102,7 @@ static inline int sas_ss_flags(unsigned long sp) | @@ -102,7 +102,7 @@ static inline int sas_ss_flags(unsigned long sp) | ||
102 | : on_sig_stack(sp) ? SS_ONSTACK : 0); | 102 | : on_sig_stack(sp) ? SS_ONSTACK : 0); |
103 | } | 103 | } |
104 | 104 | ||
105 | -static inline int host_to_target_signal(int sig) | 105 | +int host_to_target_signal(int sig) |
106 | { | 106 | { |
107 | if (sig > 64) | 107 | if (sig > 64) |
108 | return sig; | 108 | return sig; |
linux-user/syscall.c
@@ -3643,6 +3643,20 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, | @@ -3643,6 +3643,20 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, | ||
3643 | } | 3643 | } |
3644 | #endif | 3644 | #endif |
3645 | 3645 | ||
3646 | +/* Map host to target signal numbers for the wait family of syscalls. | ||
3647 | + Assume all other status bits are the same. */ | ||
3648 | +static int host_to_target_waitstatus(int status) | ||
3649 | +{ | ||
3650 | + if (WIFSIGNALED(status)) { | ||
3651 | + return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); | ||
3652 | + } | ||
3653 | + if (WIFSTOPPED(status)) { | ||
3654 | + return (host_to_target_signal(WSTOPSIG(status)) << 8) | ||
3655 | + | (status & 0xff); | ||
3656 | + } | ||
3657 | + return status; | ||
3658 | +} | ||
3659 | + | ||
3646 | int get_osversion(void) | 3660 | int get_osversion(void) |
3647 | { | 3661 | { |
3648 | static int osversion; | 3662 | static int osversion; |
@@ -3786,7 +3800,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3786,7 +3800,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
3786 | int status; | 3800 | int status; |
3787 | ret = get_errno(waitpid(arg1, &status, arg3)); | 3801 | ret = get_errno(waitpid(arg1, &status, arg3)); |
3788 | if (!is_error(ret) && arg2 | 3802 | if (!is_error(ret) && arg2 |
3789 | - && put_user_s32(status, arg2)) | 3803 | + && put_user_s32(host_to_target_waitstatus(status), arg2)) |
3790 | goto efault; | 3804 | goto efault; |
3791 | } | 3805 | } |
3792 | break; | 3806 | break; |
@@ -5136,6 +5150,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -5136,6 +5150,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
5136 | ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); | 5150 | ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); |
5137 | if (!is_error(ret)) { | 5151 | if (!is_error(ret)) { |
5138 | if (status_ptr) { | 5152 | if (status_ptr) { |
5153 | + status = host_to_target_waitstatus(status); | ||
5139 | if (put_user_s32(status, status_ptr)) | 5154 | if (put_user_s32(status, status_ptr)) |
5140 | goto efault; | 5155 | goto efault; |
5141 | } | 5156 | } |