Blame SOURCES/gdb-rhbz1870031-p10-prefixed-insn-1of3.patch

4a80f0
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
4a80f0
From: Keith Seitz <keiths@redhat.com>
4a80f0
Date: Thu, 6 May 2021 14:12:00 -0400
4a80f0
Subject: gdb-rhbz1870031-p10-prefixed-insn-1of3.patch
4a80f0
4a80f0
;; Backport "displaced stepping across addpcis/lnia"
4a80f0
;; (Will Schmidt, RHBZ 1870031)
4a80f0
4a80f0
   commit e3d528d7e6a6b863d30aaecf74adf8c78286f84c
4a80f0
   Author: Will Schmidt <will_schmidt@vnet.ibm.com>
4a80f0
   Date:   Mon Apr 12 13:35:54 2021 -0500
4a80f0
4a80f0
    [PATCH, rs6000, v3][PR gdb/27525] displaced stepping across addpcis/lnia.
4a80f0
4a80f0
      This addresses PR gdb/27525.     The lnia and other variations
4a80f0
    of the addpcis instruction write the value of the NIA into a target register.
4a80f0
    If we are single-stepping across a breakpoint, the instruction is executed
4a80f0
    from a displaced location, and thusly the written value of the PC/NIA
4a80f0
    will be incorrect.   The changes here will measure the displacement
4a80f0
    offset, and adjust the target register value to compensate.
4a80f0
4a80f0
    YYYY-MM-DD  Will Schmidt  <will_schmidt@vnet.ibm.com>
4a80f0
4a80f0
    gdb/ChangeLog:
4a80f0
4a80f0
            * rs6000-tdep.c (ppc_displaced_step_fixup): Update to handle
4a80f0
            the addpcis/lnia instruction.
4a80f0
4a80f0
    gdb/testsuite/ChangeLog:
4a80f0
4a80f0
            * gdb.arch/powerpc-addpcis.exp: Testcase harness to
4a80f0
            exercise single-stepping over subpcis,lnia,addpcis instructions
4a80f0
            with displacement.
4a80f0
            * gdb.arch/powerpc-addpcis.s: Testcase with stream
4a80f0
            of addpcis/lnia/subpcis instructions.
4a80f0
            * gdb.arch/powerpc-lnia.exp: Testcase harness to exercise
4a80f0
            single-stepping over lnia instructions with displacement.
4a80f0
            * gdb.arch/powerpc-lnia.s: Testcase with stream of
4a80f0
            lnia instructions.
4a80f0
4a80f0
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
4a80f0
--- a/gdb/rs6000-tdep.c
4a80f0
+++ b/gdb/rs6000-tdep.c
4a80f0
@@ -836,6 +836,12 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
4a80f0
 #define STHCX_INSTRUCTION 0x7c0005ad
4a80f0
 #define STQCX_INSTRUCTION 0x7c00016d
4a80f0
 
4a80f0
+/* Instruction masks for single-stepping of addpcis/lnia.  */
4a80f0
+#define ADDPCIS_INSN            0x4c000004
4a80f0
+#define ADDPCIS_INSN_MASK       0xfc00003e
4a80f0
+#define ADDPCIS_TARGET_REGISTER 0x03F00000
4a80f0
+#define ADDPCIS_INSN_REGSHIFT   21
4a80f0
+
4a80f0
 /* Check if insn is one of the Load And Reserve instructions used for atomic
4a80f0
    sequences.  */
4a80f0
 #define IS_LOAD_AND_RESERVE_INSN(insn)	((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \
4a80f0
@@ -923,8 +929,31 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
4a80f0
 			paddress (gdbarch, from), paddress (gdbarch, to));
4a80f0
 
4a80f0
 
4a80f0
+  /* Handle the addpcis/lnia instruction.  */
4a80f0
+  if ((insn & ADDPCIS_INSN_MASK) == ADDPCIS_INSN)
4a80f0
+    {
4a80f0
+      LONGEST displaced_offset;
4a80f0
+      ULONGEST current_val;
4a80f0
+      /* Measure the displacement.  */
4a80f0
+      displaced_offset = from - to;
4a80f0
+      /* Identify the target register that was updated by the instruction.  */
4a80f0
+      int regnum = (insn & ADDPCIS_TARGET_REGISTER) >> ADDPCIS_INSN_REGSHIFT;
4a80f0
+      /* Read and update the target value.  */
4a80f0
+      regcache_cooked_read_unsigned (regs, regnum , &current_val);
4a80f0
+      if (debug_displaced)
4a80f0
+	fprintf_unfiltered (gdb_stdlog,
4a80f0
+			    "displaced: {ppc} addpcis target regnum %d was "
4a80f0
+			    "0x%lx now 0x%lx",
4a80f0
+			    regnum, current_val,
4a80f0
+			    current_val + displaced_offset);
4a80f0
+      regcache_cooked_write_unsigned (regs, regnum,
4a80f0
+					current_val + displaced_offset);
4a80f0
+      /* point the PC back at the non-displaced instruction.  */
4a80f0
+      regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
4a80f0
+				    from + offset);
4a80f0
+    }
4a80f0
   /* Handle PC-relative branch instructions.  */
4a80f0
-  if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN)
4a80f0
+  else if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN)
4a80f0
     {
4a80f0
       ULONGEST current_pc;
4a80f0