From 5c1eda30f55e9c543de26fec0246f4d7655c81e4 Mon Sep 17 00:00:00 2001 From: Andreas Arnez Date: Fri, 13 Jul 2018 12:46:14 +0200 Subject: [PATCH] S390: Fix displaced stepping of "basr r,0" 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 | 5 +++++ gdb/s390-tdep.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cc61dab5861..7b808eb3a76 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2018-07-13 Andreas Arnez + + * s390-tdep.c (s390_displaced_step_fixup): Adjust PC for a + non-branching basr. + 2018-07-12 Philippe Waroquiers * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index 77e64af5839..e962824ca04 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -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. */ -- 2.30.2