diff options
author | Maciej W. Rozycki <macro@codesourcery.com> | 2014-10-05 21:50:47 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@codesourcery.com> | 2014-10-05 21:50:47 +0100 |
commit | ae79065284d6250c27377b5ca1dce54da9b1d4ba (patch) | |
tree | df4f921408584d2897ed09efac7ffa0c990357d3 | |
parent | 24340e81faf9d23de6456293954de73785e53d3f (diff) | |
download | gdb-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/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 21 |
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) */ } |