aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@codesourcery.com>2014-10-05 21:50:47 +0100
committerMaciej W. Rozycki <macro@codesourcery.com>2014-10-05 21:50:47 +0100
commitae79065284d6250c27377b5ca1dce54da9b1d4ba (patch)
treedf4f921408584d2897ed09efac7ffa0c990357d3
parent24340e81faf9d23de6456293954de73785e53d3f (diff)
downloadgdb-ae79065284d6250c27377b5ca1dce54da9b1d4ba.zip
gdb-ae79065284d6250c27377b5ca1dce54da9b1d4ba.tar.gz
gdb-ae79065284d6250c27377b5ca1dce54da9b1d4ba.tar.bz2
MIPS: Correct MUSTBE32 interpretation in delay slot handling
This change addresses `micromips_instruction_has_delay_slot' and `mips16_instruction_has_delay_slot' that both incorrectly interpret their MUSTBE32 argument. Their callers assume that when the flag is clear these functions will return 1 when any non-compact jump or branch instruction is present at ADDR, while in fact they will only return 1 for 16-bit such instructions only. This change makes the implementation match the expectations. * mips-tdep.c (micromips_instruction_has_delay_slot): When !mustbe32 also return 1 for 32-bit instructions. (mips16_instruction_has_delay_slot): Likewise. Add an explanatory comment.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/mips-tdep.c21
2 files changed, 20 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6387550..ee1f934 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2014-10-05 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * mips-tdep.c (micromips_instruction_has_delay_slot): When
+ !mustbe32 also return 1 for 32-bit instructions.
+ (mips16_instruction_has_delay_slot): Likewise. Add an
+ explanatory comment.
+
2014-10-03 Maciej W. Rozycki <macro@codesourcery.com>
* elfread.c (elf_symtab_read): Also mark solib trampoline minimal
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 188580f..7e07673 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -7035,17 +7035,18 @@ micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
if (status)
return 0;
- if (!mustbe32) /* 16-bit instructions. */
- return (micromips_op (insn) == 0x11
+ /* 16-bit instructions. */
+ if ((micromips_op (insn) == 0x11
/* POOL16C: bits 010001 */
- && (b5s5_op (insn) == 0xc
+ && (b5s5_op (insn) == 0xc
/* JR16: bits 010001 01100 */
- || (b5s5_op (insn) & 0x1e) == 0xe))
+ || (b5s5_op (insn) & 0x1e) == 0xe))
/* JALR16, JALRS16: bits 010001 0111x */
- || (micromips_op (insn) & 0x37) == 0x23
+ || (micromips_op (insn) & 0x37) == 0x23
/* BEQZ16, BNEZ16: bits 10x011 */
- || micromips_op (insn) == 0x33;
+ || micromips_op (insn) == 0x33)
/* B16: bits 110011 */
+ return !mustbe32;
/* 32-bit instructions. */
if (micromips_op (insn) == 0x0)
@@ -7091,6 +7092,10 @@ micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
/* JALX: bits 111100 */
}
+/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay
+ slot (i.e. it is a non-compact jump instruction). The instruction
+ must be 32-bit if MUSTBE32 is set or can be any instruction otherwise. */
+
static int
mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
int mustbe32)
@@ -7102,8 +7107,8 @@ mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
if (status)
return 0;
- if (!mustbe32)
- return (inst & 0xf89f) == 0xe800; /* JR/JALR (16-bit instruction) */
+ if ((inst & 0xf89f) == 0xe800) /* JR/JALR (16-bit instruction) */
+ return !mustbe32;
return (inst & 0xf800) == 0x1800; /* JAL/JALX (32-bit instruction) */
}