S390: Fix displaced stepping of "basr r,0"
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Fri, 13 Jul 2018 10:46:14 +0000 (12:46 +0200)
committerAndreas Arnez <arnez@linux.vnet.ibm.com>
Fri, 13 Jul 2018 10:46:14 +0000 (12:46 +0200)
The BASR instruction behaves differently depending on whether the second
operand is a number from 1 to 15, or zero.  In the former case BASR jumps
to the address contained in the general register of that number, but in
the latter case no jump is performed.  GDB's displaced-stepping logic does
not distinguish these cases, although it should.

This is fixed.  In the case where no jump is performed the PC is adjusted
to point back after the original instruction.  Otherwise the PC is left
alone.

gdb/ChangeLog:

* s390-tdep.c (s390_displaced_step_fixup): Adjust PC for a
non-branching basr.

gdb/ChangeLog
gdb/s390-tdep.c

index cc61dab5861609cf247a104347761af24b2913f5..7b808eb3a7601140f707fb9a232791f93aa8bb5b 100644 (file)
@@ -1,3 +1,8 @@
+2018-07-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+       * s390-tdep.c (s390_displaced_step_fixup): Adjust PC for a
+       non-branching basr.
+
 2018-07-12  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 
        * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add
index 77e64af58399d5bd50894b17e8f761b57f5e814b..e962824ca0471b3279d0dcc2fac82068a0f0d401 100644 (file)
@@ -492,6 +492,9 @@ s390_displaced_step_fixup (struct gdbarch *gdbarch,
       /* Recompute saved return address in R1.  */
       regcache_cooked_write_unsigned (regs, S390_R0_REGNUM + r1,
                                      amode | (from + insnlen));
+      /* Update PC iff the instruction doesn't actually branch.  */
+      if (insn[0] == op_basr && r2 == 0)
+       regcache_write_pc (regs, from + insnlen);
     }
 
   /* Handle absolute branch instructions.  */