From patchwork Sat Sep 15 20:24:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 184101 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8F2B42C0093 for ; Sun, 16 Sep 2012 06:24:47 +1000 (EST) Received: from localhost ([::1]:41668 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCyuz-0007TP-Hu for incoming@patchwork.ozlabs.org; Sat, 15 Sep 2012 16:24:45 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49015) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCyuc-0007BA-VU for qemu-devel@nongnu.org; Sat, 15 Sep 2012 16:24:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TCyub-0004hZ-4n for qemu-devel@nongnu.org; Sat, 15 Sep 2012 16:24:22 -0400 Received: from mail-pz0-f45.google.com ([209.85.210.45]:37441) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TCyua-0004gA-Uh for qemu-devel@nongnu.org; Sat, 15 Sep 2012 16:24:21 -0400 Received: by mail-pz0-f45.google.com with SMTP id n15so3318847dad.4 for ; Sat, 15 Sep 2012 13:24:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=hAzW02R/0dYcGHHVNyNXC8478o1E02yCLbsnOlclDEI=; b=D3LIpuLwielSXuSK7AbdMqP3K8J0LWLOTryaOxMMHfMQRgQ9ilXZgPxEhAPmuIaEMi LIGtMrZSCqAUf3tGHrEyLB/XadLuSJZDxC8aGPPKkgzWI6EAHF2HYzqhHZBxvO2CTnsg lQ18mggI0dBiaiNaAdSfMtgIZGpkI8jwpiVfmih2JHrIhIchQNJcUBW/m0iRa/PkvclC Xv0qOBWeNlUaWi6cJi6uChoYwlBPl/EsaAG86n13u0D4jJJ/LSRlUJyFYCXb2e1m4Lyp sRGxOm7MrzCp5rvHj8/w8V8W+SFX0kBYhnVMwSg32Z/N/s0zjzsbMTQnoKjapS9I4LN5 CUCw== Received: by 10.68.226.38 with SMTP id rp6mr12096201pbc.116.1347740660642; Sat, 15 Sep 2012 13:24:20 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id lb1sm3553987pbc.47.2012.09.15.13.24.19 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 15 Sep 2012 13:24:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 15 Sep 2012 13:24:09 -0700 Message-Id: <1347740649-28646-7-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1347740649-28646-1-git-send-email-rth@twiddle.net> References: <1347740649-28646-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.45 Cc: Riku Voipio Subject: [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Compare signal numbers in the proper domain. Convert all of the fields for SIGIO and SIGCHLD. Signed-off-by: Richard Henderson --- linux-user/qemu.h | 3 +++ linux-user/signal.c | 59 +++++++++++++++++++++++++++++++++++----------------- linux-user/syscall.c | 2 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 69b27d7..8f871eb 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -219,6 +219,9 @@ unsigned long init_guest_space(unsigned long host_start, #include "qemu-log.h" +/* syscall.c */ +int host_to_target_waitstatus(int status); + /* strace.c */ void print_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, diff --git a/linux-user/signal.c b/linux-user/signal.c index bf2dfb8..9842ba6 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -202,46 +202,67 @@ void target_to_host_old_sigset(sigset_t *sigset, static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) { - int sig; - sig = host_to_target_signal(info->si_signo); + int sig = host_to_target_signal(info->si_signo); tinfo->si_signo = sig; tinfo->si_errno = 0; tinfo->si_code = info->si_code; - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - /* should never come here, but who knows. The information for - the target is irrelevant */ + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + /* Should never come here, but who knows. The information for + the target is irrelevant. */ tinfo->_sifields._sigfault._addr = 0; - } else if (sig == SIGIO) { + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band = info->si_band; tinfo->_sifields._sigpoll._fd = info->si_fd; + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid = info->si_pid; + tinfo->_sifields._sigchld._uid = info->si_uid; + tinfo->_sifields._sigchld._status + = host_to_target_waitstatus(info->si_status); + tinfo->_sifields._sigchld._utime = info->si_utime; + tinfo->_sifields._sigchld._stime = info->si_stime; } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = info->si_pid; tinfo->_sifields._rt._uid = info->si_uid; /* XXX: potential problem if 64 bit */ - tinfo->_sifields._rt._sigval.sival_ptr = - (abi_ulong)(unsigned long)info->si_value.sival_ptr; + tinfo->_sifields._rt._sigval.sival_ptr + = (abi_ulong)(unsigned long)info->si_value.sival_ptr; } } static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) { - int sig; - sig = info->si_signo; + int sig = info->si_signo; tinfo->si_signo = tswap32(sig); tinfo->si_errno = tswap32(info->si_errno); tinfo->si_code = tswap32(info->si_code); - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - tinfo->_sifields._sigfault._addr = - tswapal(info->_sifields._sigfault._addr); - } else if (sig == SIGIO) { - tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + tinfo->_sifields._sigfault._addr + = tswapal(info->_sifields._sigfault._addr); + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band + = tswap32(info->_sifields._sigpoll._band); + tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid + = tswap32(info->_sifields._sigchld._pid); + tinfo->_sifields._sigchld._uid + = tswap32(info->_sifields._sigchld._uid); + tinfo->_sifields._sigchld._status + = tswap32(info->_sifields._sigchld._status); + tinfo->_sifields._sigchld._utime + = tswapal(info->_sifields._sigchld._utime); + tinfo->_sifields._sigchld._stime + = tswapal(info->_sifields._sigchld._stime); } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); - tinfo->_sifields._rt._sigval.sival_ptr = - tswapal(info->_sifields._rt._sigval.sival_ptr); + tinfo->_sifields._rt._sigval.sival_ptr + = tswapal(info->_sifields._rt._sigval.sival_ptr); } } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 925e579..3676c72 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4920,7 +4920,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, /* Map host to target signal numbers for the wait family of syscalls. Assume all other status bits are the same. */ -static int host_to_target_waitstatus(int status) +int host_to_target_waitstatus(int status) { if (WIFSIGNALED(status)) { return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);