[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/11] linux-user: Check type of microMIPS break ins
From: |
riku . voipio |
Subject: |
[Qemu-devel] [PATCH 09/11] linux-user: Check type of microMIPS break instruction |
Date: |
Fri, 27 Sep 2013 15:10:04 +0300 |
From: Kwok Cheung Yeung <address@hidden>
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 <address@hidden>
Signed-off-by: Riku Voipio <address@hidden>
---
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 016e2e1..1561950 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2400,12 +2400,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);
@@ -2413,26 +2432,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) {
--
1.8.1.2
- [Qemu-devel] [PULL] [PATCH 00/11] Linux-user updates, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 01/11] alpha-linux-user: Fix umount syscall numbers, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 03/11] linux-user: convert /proc/net/route when endianess differs, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 05/11] linux-user: allow use of TIOCGSID, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 02/11] mips-linux-user: Adjust names in mips_syscall_args, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 04/11] linux-user: Add setsockopt(SO_ATTACH_FILTER), riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 08/11] linux-user: correct how SOL_SOCKET is converted from target to host and back, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 09/11] linux-user: Check type of microMIPS break instruction,
riku . voipio <=
- [Qemu-devel] [PATCH 10/11] [v2] linux-user: implement m68k atomic syscalls, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 07/11] linux-user: add support of binfmt_misc 'O' flag, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 11/11] linux-user: Handle SOCK_CLOEXEC/NONBLOCK if unavailable on host, riku . voipio, 2013/09/27
- [Qemu-devel] [PATCH 06/11] linux-user: add some IPV6 commands in setsockop(), riku . voipio, 2013/09/27
- Re: [Qemu-devel] [PULL] [PATCH 00/11] Linux-user updates, Edgar E. Iglesias, 2013/09/27