From patchwork Tue Sep 10 00:36:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kwok Cheung Yeung X-Patchwork-Id: 273734 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 95D892C00A2 for ; Tue, 10 Sep 2013 10:37:29 +1000 (EST) Received: from localhost ([::1]:54225 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJBxP-0001sg-LV for incoming@patchwork.ozlabs.org; Mon, 09 Sep 2013 20:37:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJBx1-0001sZ-C2 for qemu-devel@nongnu.org; Mon, 09 Sep 2013 20:37:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VJBwt-0007pv-UC for qemu-devel@nongnu.org; Mon, 09 Sep 2013 20:37:03 -0400 Received: from relay1.mentorg.com ([192.94.38.131]:38742) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJBwt-0007pq-OD for qemu-devel@nongnu.org; Mon, 09 Sep 2013 20:36:55 -0400 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1VJBwq-00059c-9G from Kwok_Yeung@mentor.com ; Mon, 09 Sep 2013 17:36:52 -0700 Received: from SVR-ORW-FEM-03.mgc.mentorg.com ([147.34.97.39]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 9 Sep 2013 17:36:51 -0700 Received: from build4-lucid-cs (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.2.247.3; Mon, 9 Sep 2013 17:36:51 -0700 Received: by build4-lucid-cs (Postfix, from userid 49858) id 41A6B409C3; Mon, 9 Sep 2013 17:36:51 -0700 (PDT) From: Kwok Cheung Yeung To: , Date: Mon, 9 Sep 2013 17:36:40 -0700 Message-ID: <1378773400-20104-1-git-send-email-kcy@codesourcery.com> X-Mailer: git-send-email 1.7.4.1 MIME-Version: 1.0 X-OriginalArrivalTime: 10 Sep 2013 00:36:51.0791 (UTC) FILETIME=[D79985F0:01CEADBD] X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 Cc: Kwok Cheung Yeung , riku.voipio@iki.fi, aurelien@aurel32.net Subject: [Qemu-devel] [PATCH] linux-user: Check type of microMIPS break instruction 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 microMIPS instructions that cause breakpoint exceptions come in 16-bit and 32-bit variants. When handling exceptions caused by such instructions, the instruction type needs to be taken into account when extracting the break code. The code has also been restructured for better clarity. Signed-off-by: Kwok Cheung Yeung --- linux-user/main.c | 56 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 5c2f7b2..8eaf33a 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2318,12 +2318,31 @@ done_syscall: if (env->hflags & MIPS_HFLAG_M16) { if (env->insn_flags & ASE_MICROMIPS) { /* microMIPS mode */ - abi_ulong instr[2]; - - ret = get_user_u16(instr[0], env->active_tc.PC) || - get_user_u16(instr[1], env->active_tc.PC + 2); + ret = get_user_u16(trap_instr, env->active_tc.PC); + if (ret != 0) { + goto error; + } - trap_instr = (instr[0] << 16) | instr[1]; + if ((trap_instr >> 10) == 0x11) { + /* 16-bit instruction */ + code = trap_instr & 0xf; + } else { + /* 32-bit instruction */ + abi_ulong instr_lo; + + ret = get_user_u16(instr_lo, + env->active_tc.PC + 2); + if (ret != 0) { + goto error; + } + trap_instr = (trap_instr << 16) | instr_lo; + code = ((trap_instr >> 6) & ((1 << 20) - 1)); + /* Unfortunately, microMIPS also suffers from + the old assembler bug... */ + if (code >= (1 << 10)) { + code >>= 10; + } + } } else { /* MIPS16e mode */ ret = get_user_u16(trap_instr, env->active_tc.PC); @@ -2331,26 +2350,21 @@ done_syscall: goto error; } code = (trap_instr >> 6) & 0x3f; - if (do_break(env, &info, code) != 0) { - goto error; - } - break; } } else { ret = get_user_ual(trap_instr, env->active_tc.PC); - } - - if (ret != 0) { - goto error; - } + if (ret != 0) { + goto error; + } - /* As described in the original Linux kernel code, the - * below checks on 'code' are to work around an old - * assembly bug. - */ - code = ((trap_instr >> 6) & ((1 << 20) - 1)); - if (code >= (1 << 10)) { - code >>= 10; + /* As described in the original Linux kernel code, the + * below checks on 'code' are to work around an old + * assembly bug. + */ + code = ((trap_instr >> 6) & ((1 << 20) - 1)); + if (code >= (1 << 10)) { + code >>= 10; + } } if (do_break(env, &info, code) != 0) {