Backport "PowerPC remove 512 bytes region limit if 2nd DAWR is available"

(Rogerio Alves, RHBZ 1870029)
Backport patches for "Support prefixed instructions in GDB"
(Will Schmidt and Luis Machado, RHBZ 1870031)

Resolves: rhbz#1870029
Resolves: rhbz#1870031
This commit is contained in:
Keith Seitz 2021-06-28 18:37:39 -04:00
parent 5e64226ec7
commit 4748efc8fa
8 changed files with 870 additions and 1 deletions

View File

@ -419,3 +419,18 @@ Patch100: gdb-rhbz1971095-libthread_db-update-4of5.patch
# (Kevin Buettner, RH BZ 1971095)
Patch101: gdb-rhbz1971095-libthread_db-update-5of5.patch
# Backport "PowerPC remove 512 bytes region limit if 2nd DAWR is available"
# (Rogerio Alves, RHBZ 1870029)
Patch102: gdb-rhbz1870029-powerpc-remove-region-limit-dawr.patch
# Backport "displaced stepping across addpcis/lnia"
# (Will Schmidt, RHBZ 1870031)
Patch103: gdb-rhbz1870031-p10-prefixed-insn-1of3.patch
# Backport "gdb-power10-single-step"
# (Will Schmidt, RHBZ 1870031)
Patch104: gdb-rhbz1870031-p10-prefixed-insn-2of3.patch
# Backport "Fix build failure for 32-bit targets with..."
# (Luis Machado, RHBZ 1870031)
Patch105: gdb-rhbz1870031-p10-prefixed-insn-3of3.patch

View File

@ -99,3 +99,7 @@
%patch099 -p1
%patch100 -p1
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
%patch105 -p1

View File

@ -99,3 +99,7 @@ gdb-rhbz1971095-libthread_db-update-2of5.patch
gdb-rhbz1971095-libthread_db-update-3of5.patch
gdb-rhbz1971095-libthread_db-update-4of5.patch
gdb-rhbz1971095-libthread_db-update-5of5.patch
gdb-rhbz1870029-powerpc-remove-region-limit-dawr.patch
gdb-rhbz1870031-p10-prefixed-insn-1of3.patch
gdb-rhbz1870031-p10-prefixed-insn-2of3.patch
gdb-rhbz1870031-p10-prefixed-insn-3of3.patch

View File

@ -0,0 +1,79 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Wed, 5 May 2021 09:11:12 -0700
Subject: gdb-rhbz1870029-powerpc-remove-region-limit-dawr.patch
;; Backport "PowerPC remove 512 bytes region limit if 2nd DAWR is available"
;; (Rogerio Alves, RHBZ 1870029)
commit 539d71e89a21990d9fd15641477e4790129bdb11
Author: Rogerio Alves <rcardoso@linux.ibm.com>
Date: Tue Dec 1 16:53:38 2020 -0300
PowerPC remove 512 bytes region limit if 2nd DAWR is avaliable.
Power 10 introduces the 2nd DAWR (second watchpoint) and also removed
a restriction that limit the watch region to 512 bytes.
2020-11-08 Rogerio A. Cardoso <rcardoso@linux.ibm.com>
/gdb
* ppc-linux-nat.c: (PPC_DEBUG_FEATURE_DATA_BP_ARCH_31): New define.
(region_ok_for_hw_watchpoint): Check if 2nd DAWR is avaliable before
set region.
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -138,6 +138,11 @@ struct ppc_hw_breakpoint
#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
#endif /* PPC_DEBUG_FEATURE_DATA_BP_DAWR */
+/* Feature defined on Linux kernel v5.1: Second watchpoint support. */
+#ifndef PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
+#define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x20
+#endif /* PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 */
+
/* The version of the PowerPC HWDEBUG kernel interface that we will use, if
available. */
#define PPC_DEBUG_CURRENT_VERSION 1
@@ -2108,9 +2113,10 @@ ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
watchpoints. */
if (m_dreg_interface.hwdebug_p ())
{
- int region_size;
const struct ppc_debug_info &hwdebug_info = (m_dreg_interface
.hwdebug_info ());
+ int region_size = hwdebug_info.data_bp_alignment;
+ int region_align = region_size;
/* Embedded DAC-based processors, like the PowerPC 440 have ranged
watchpoints and can watch any access within an arbitrary memory
@@ -2122,15 +2128,19 @@ ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
return 2;
/* Check if the processor provides DAWR interface. */
if (hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_DAWR)
- /* DAWR interface allows to watch up to 512 byte wide ranges which
- can't cross a 512 byte boundary. */
- region_size = 512;
- else
- region_size = hwdebug_info.data_bp_alignment;
+ {
+ /* DAWR interface allows to watch up to 512 byte wide ranges. */
+ region_size = 512;
+ /* DAWR interface allows to watch up to 512 byte wide ranges which
+ can't cross a 512 byte bondary on machines that doesn't have a
+ second DAWR (P9 or less). */
+ if (!(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_ARCH_31))
+ region_align = 512;
+ }
/* Server processors provide one hardware watchpoint and addr+len should
fall in the watchable region provided by the ptrace interface. */
- if (region_size
- && (addr + len > (addr & ~(region_size - 1)) + region_size))
+ if (region_align
+ && (addr + len > (addr & ~(region_align - 1)) + region_size))
return 0;
}
/* addr+len must fall in the 8 byte watchable region for DABR-based

View File

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

View File

@ -0,0 +1,633 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Thu, 6 May 2021 14:53:00 -0400
Subject: gdb-rhbz1870031-p10-prefixed-insn-2of3.patch
;; Backport "gdb-power10-single-step"
;; (Will Schmidt, RHBZ 1870031)
commit c8a379440e0f8bf94ed5730e823c9256e64bf37c
Author: Will Schmidt <will_schmidt@vnet.ibm.com>
Date: Mon Apr 12 14:11:02 2021 -0500
[PATCH] gdb-power10-single-step
Hi,
This is based on a patch originally written by Alan Modra.
Powerpc / Power10 ISA 3.1 adds prefixed instructions, which
are 8 bytes in length. This is in contrast to powerpc previously
always having 4 byte instruction length. This patch implements
changes to allow GDB to better detect prefixed instructions, and
handle single stepping across the 8 byte instructions.
Added #defines to help test for PNOP and prefix instructions.
Update ppc_displaced_step_copy_insn() to handle pnop and prefixed
instructions whem R=0 (non-pc-relative).
Updated ppc_displaced_step_fixup() to properly handle the offset
value matching the current instruction size
Updated the for-loop within ppc_deal_with_atomic_sequence() to
count instructions properly in case we have a mix of 4-byte and
8-byte instructions within the atomic_sequence_length.
Added testcase and harness to exercise pc-relative load/store
instructions with R=0.
2021-04-12 Will Schmidt <will_schmidt@vnet.ibm.com>
gdb/ChangeLog:
* rs6000-tdep.c: Add support for single-stepping of
prefixed instructions.
gdb/testsuite/ChangeLog:
* gdb.arch/powerpc-plxv-nonrel.s: Testcase using
non-relative plxv instructions.
* gdb.arch/powerpc-plxv-nonrel.exp: Testcase harness.
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -814,7 +814,7 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
rs6000_breakpoint;
/* Instruction masks for displaced stepping. */
-#define BRANCH_MASK 0xfc000000
+#define OP_MASK 0xfc000000
#define BP_MASK 0xFC0007FE
#define B_INSN 0x48000000
#define BC_INSN 0x40000000
@@ -842,6 +842,11 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
#define ADDPCIS_TARGET_REGISTER 0x03F00000
#define ADDPCIS_INSN_REGSHIFT 21
+#define PNOP_MASK 0xfff3ffff
+#define PNOP_INSN 0x07000000
+#define R_MASK 0x00100000
+#define R_ZERO 0x00000000
+
/* Check if insn is one of the Load And Reserve instructions used for atomic
sequences. */
#define IS_LOAD_AND_RESERVE_INSN(insn) ((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \
@@ -873,10 +878,38 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int insn;
- read_memory (from, buf, len);
+ len = target_read (current_inferior()->top_target(), TARGET_OBJECT_MEMORY, NULL,
+ buf, from, len);
+ if ((ssize_t) len < PPC_INSN_SIZE)
+ memory_error (TARGET_XFER_E_IO, from);
insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+ /* Check for PNOP and for prefixed instructions with R=0. Those
+ instructions are safe to displace. Prefixed instructions with R=1
+ will read/write data to/from locations relative to the current PC.
+ We would not be able to fixup after an instruction has written data
+ into a displaced location, so decline to displace those instructions. */
+ if ((insn & OP_MASK) == 1 << 26)
+ {
+ if (((insn & PNOP_MASK) != PNOP_INSN)
+ && ((insn & R_MASK) != R_ZERO))
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "displaced: {ppc} Not displacing prefixed "
+ "instruction %08x at %s",
+ insn, paddress (gdbarch, from));
+ return NULL;
+ }
+ }
+ else
+ /* Non-prefixed instructions.. */
+ {
+ /* Set the instruction length to 4 to match the actual instruction
+ length. */
+ len = 4;
+ }
+
/* Assume all atomic sequences start with a Load and Reserve instruction. */
if (IS_LOAD_AND_RESERVE_INSN (insn))
{
@@ -917,11 +950,17 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_;
ULONGEST insn = extract_unsigned_integer (closure->buf.data (),
PPC_INSN_SIZE, byte_order);
- ULONGEST opcode = 0;
+ ULONGEST opcode;
/* Offset for non PC-relative instructions. */
- LONGEST offset = PPC_INSN_SIZE;
+ LONGEST offset;
- opcode = insn & BRANCH_MASK;
+ opcode = insn & OP_MASK;
+
+ /* Set offset to 8 if this is an 8-byte (prefixed) instruction. */
+ if ((opcode) == 1 << 26)
+ offset = 2 * PPC_INSN_SIZE;
+ else
+ offset = PPC_INSN_SIZE;
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
@@ -1058,13 +1097,16 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
instructions. */
for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
{
- loc += PPC_INSN_SIZE;
+ if ((insn & OP_MASK) == 1 << 26)
+ loc += 2 * PPC_INSN_SIZE;
+ else
+ loc += PPC_INSN_SIZE;
insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
/* Assume that there is at most one conditional branch in the atomic
sequence. If a conditional branch is found, put a breakpoint in
its destination address. */
- if ((insn & BRANCH_MASK) == BC_INSN)
+ if ((insn & OP_MASK) == BC_INSN)
{
int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
int absolute = insn & 2;
@@ -7095,7 +7137,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_displaced_step_location (gdbarch,
displaced_step_at_entry_point);
- set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
+ set_gdbarch_max_insn_length (gdbarch, 2 * PPC_INSN_SIZE);
/* Hook in ABI-specific overrides, if they have been registered. */
info.target_desc = tdesc;
diff --git a/gdb/testsuite/gdb.arch/powerpc-addpcis.exp b/gdb/testsuite/gdb.arch/powerpc-addpcis.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-addpcis.exp
@@ -0,0 +1,104 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# Test to confirm that gdb is properly single stepping over the
+# displaced addpcis instruction.
+# The addpcis instruction and its extended mnemonics lnia and subpcis
+# apply an immediate shifted value (X || 0x0000) to the current PC/NIA
+# value, and store that value into the instructions target register.
+# When the instruction is displaced, it needs special handling.
+
+# lnia Rx == addpcis Rx,0
+# subcis Rx,value == addpcis Rx,-value
+
+if { ![istarget powerpc*-*] } {
+ verbose "Skipping powerpc addpcis test."
+ return
+}
+
+set retval 0
+
+standard_testfile .s
+
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
+ {debug quiet}] } {
+ return -1
+}
+
+if ![runto_main] then {
+ return
+}
+
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
+set bp1 *$check_pc+4
+set bp2 *$check_pc+12
+set bp3 *$check_pc+16
+gdb_breakpoint $bp1
+gdb_breakpoint $bp2
+gdb_breakpoint $bp3
+
+gdb_test "stepi" "" "set r3 "
+set check_r3 [get_hexadecimal_valueof "\$r3" "default0"]
+gdb_test "stepi" "" "set r4"
+set check_r4 [get_hexadecimal_valueof "\$r4" "default0"]
+gdb_test "stepi" "" "set r5"
+set check_r5 [get_hexadecimal_valueof "\$r5" "default0"]
+gdb_test "stepi" "" "set r6"
+set check_r6 [get_hexadecimal_valueof "\$r6" "default0"]
+gdb_test "stepi" "" "set r7"
+set check_r7 [get_hexadecimal_valueof "\$r7" "default0"]
+gdb_test "stepi" "" "set r8"
+set check_r8 [get_hexadecimal_valueof "\$r8" "default0"]
+gdb_test "stepi" "" "set r9"
+set check_r9 [get_hexadecimal_valueof "\$r9" "default0"]
+
+# R6 will contain the reference value. All other
+# instructions in this test will be storing values
+# relative to what is stored in R6.
+
+# subpcis 3,+0x100 # /* set r3 */
+# subpcis 4,+0x10 # /* set r4 */
+# subpcis 5,+0x1 # /* set r5 */
+# lnia 6 # /* set r6 */
+# addpcis 7,+0x1 # /* set r7 */
+# addpcis 8,+0x10 # /* set r8 */
+# addpcis 9,+0x100 # /* set r9 */
+
+if [expr $check_r3 + 0x1000000 != $check_r6 - 0xc ] {
+ fail "unexpected value r3 + 0x1,000,000 != r6 + 0xc ; r3: $check_r3 r6: $check_r6 "
+}
+if [expr $check_r4 + 0x100000 != $check_r6 - 0x8 ] {
+ fail "unexpected value r4 + 0x100,000 != r6 - 0x8 ; r4: $check_r4 r6: $check_r6 "
+}
+if [expr $check_r5 + 0x10000 != $check_r6 - 0x4 ] {
+ fail "unexpected value r5 + 0x10,000 != r6 , r5: $check_r5 r6: $check_r6 "
+}
+if [expr $check_r6 != $check_r6] {
+ fail "unexpected value r6 != r6 , r6: $check_r6 r6: $check_r6 "
+}
+if [expr $check_r7 - 0x10000 != $check_r6 + 0x4] {
+ fail "unexpected value r7 - 0x10,000 != r6 + 0x4 , r7: $check_r7 r7: $check_r6 "
+}
+if [expr $check_r8 - 0x100000 != $check_r6 + 0x8 ] {
+ fail "unexpected value r8 - 0x100,000 != r6 , r8: $check_r8 r8: $check_r6 "
+}
+if [expr $check_r9 - 0x1000000 != $check_r6 + 0xc ] {
+ fail "unexpected value r9 - 0x1,000,000 != r6 + 0xc , r9: $check_r9 r6: $check_r6 "
+}
+
+gdb_test "info break"
+gdb_test "info register r3 r4 r5 r6 r7 r8 r9"
+gdb_test "disas main"
diff --git a/gdb/testsuite/gdb.arch/powerpc-addpcis.s b/gdb/testsuite/gdb.arch/powerpc-addpcis.s
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-addpcis.s
@@ -0,0 +1,33 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+/* Test to confirm that gdb is properly single stepping over the
+ displaced addpcis instruction. */
+
+.global main
+.type main,function
+# addpcis: the sum of NIA + ( D || 0x0000) is placed in RT.
+main:
+ subpcis 3,+0x100 # /* set r3 */
+ subpcis 4,+0x10 # /* set r4 */
+ subpcis 5,+0x1 # /* set r5 */
+ lnia 6 # /* set r6 */
+ addpcis 7,+0x1 # /* set r7 */
+ addpcis 8,+0x10 # /* set r8 */
+ addpcis 9,+0x100 # /* set r9 */
+ blr
diff --git a/gdb/testsuite/gdb.arch/powerpc-lnia.exp b/gdb/testsuite/gdb.arch/powerpc-lnia.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-lnia.exp
@@ -0,0 +1,100 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test to see if gdb is properly single stepping over the
+# displaced lnia instruction. This test checks that a series
+# of lnia instructions are loading ascending values as expected.
+
+# lnia is an extended mnemonic for the addpcis instruction, which
+# stores the $NIA plus an immediate value into a register.
+#
+# lnia Rx == addpcis Rx,0 == lnia Rx
+# subcis Rx,value == addpcis Rx,-value
+
+if { ![istarget powerpc*-*] } {
+ verbose "Skipping powerpc lnia test."
+ return
+}
+
+set retval 0
+
+standard_testfile .s
+
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
+ {debug quiet}] } {
+ return -1
+}
+
+if ![runto_main] then {
+ return
+}
+
+set before_pc 0
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
+
+# set some breakpoints on the instructions below main().
+set bp1 *$check_pc+4
+set bp2 *$check_pc+12
+set bp3 *$check_pc+16
+gdb_breakpoint $bp1
+gdb_breakpoint $bp2
+gdb_breakpoint $bp3
+
+# single-step through the lnia instructions, and retrieve the
+# register values as we proceed.
+gdb_test "stepi" "" "set r3"
+set check_r3 [get_hexadecimal_valueof "\$r3" "default0"]
+gdb_test "stepi" "" "set r4"
+set check_r4 [get_hexadecimal_valueof "\$r4" "default0"]
+gdb_test "stepi" "" "set r5"
+set check_r5 [get_hexadecimal_valueof "\$r5" "default0"]
+gdb_test "stepi" "" "set r6"
+set check_r6 [get_hexadecimal_valueof "\$r6" "default0"]
+gdb_test "stepi" "" "set r7"
+set check_r7 [get_hexadecimal_valueof "\$r7" "default0"]
+gdb_test "stepi" "" "set r8"
+set check_r8 [get_hexadecimal_valueof "\$r8" "default0"]
+gdb_test "stepi" "" "set r9"
+set check_r9 [get_hexadecimal_valueof "\$r9" "default0"]
+
+# Ensure that our register values are as expected.
+# Specifically that the values loaded by the lnia instruction
+# reflect the value of the PC as if the instruction was
+# not displaced.
+if [expr $check_r3 + 4 != $check_r4] {
+ fail "unexpected value r3+4 != r4 , r3: $check_r3 r4: $check_r4 "
+}
+if [expr $check_r4 + 4 != $check_r5] {
+ fail "unexpected value r4+4 != r5 , r4: $check_r4 r5: $check_r5 "
+}
+if [expr $check_r5 + 4 != $check_r6] {
+ fail "unexpected value r5+4 != r6 , r5: $check_r5 r6: $check_r6 "
+}
+if [expr $check_r6 + 4 != $check_r7] {
+ fail "unexpected value r6+4 != r7 , r6: $check_r6 r7: $check_r7 "
+}
+if [expr $check_r7 + 4 != $check_r8] {
+ fail "unexpected value r7+4 != r8 , r7: $check_r7 r8: $check_r8 "
+}
+if [expr $check_r8 + 4 != $check_r9] {
+ fail "unexpected value r8+4 != r9 , r8: $check_r8 r9: $check_r9 "
+}
+
+gdb_test "info break"
+gdb_test "info register r3 r4 r5 r6 r7 r8 r9"
+gdb_test "disas main"
+
+# Let the inferior store all vector registers in a buffer, then dump
+# the buffer and check it.
diff --git a/gdb/testsuite/gdb.arch/powerpc-lnia.s b/gdb/testsuite/gdb.arch/powerpc-lnia.s
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-lnia.s
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Test to confirm that gdb properly handles lnia instructions
+ that load the current PC into a target register when executed
+ from a displaced location. */
+
+.global main
+.type main,function
+main:
+ lnia 3 # /* set r3 */
+ lnia 4 # /* set r4 */
+ lnia 5 # /* set r5 */
+ lnia 6 # /* set r6 */
+ lnia 7 # /* set r7 */
+ lnia 8 # /* set r8 */
+ lnia 9 # /* set r9 */
+ blr
diff --git a/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.exp
@@ -0,0 +1,130 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test to see if gdb is properly single stepping over the
+# displaced plxv instruction.
+
+if { ![istarget powerpc*-*] } {
+ verbose "Skipping powerpc plxv test."
+ return
+}
+
+set retval 0
+
+standard_testfile .s
+
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile" \
+ {debug quiet}] } {
+ return -1
+}
+
+gdb_test "set radix 0b10000"
+gdb_test "set debug displaced"
+
+if ![runto_main] then {
+ return
+}
+
+gdb_test "set debug displaced on"
+
+# Proc to extract the uint128 hex value from the output of
+# a print vector statement.
+proc get_vector_hexadecimal_valueof { exp default {test ""} } {
+ set val "0x0000"
+ global gdb_prompt
+ if {$test == ""} {
+ set test "get vector_hexadecimal valueof \"${exp}\""
+ }
+ gdb_test_multiple "print $${exp}.uint128" $test {
+ -re -wrap "\\$\[0-9\]* = (0x\[0-9a-zA-Z\]+).*" {
+ set val $expect_out(1,string)
+ pass "$test"
+ }
+ -re -wrap ".*Illegal instruction.* $" {
+ fail "Illegal instruction on print."
+ set val 0xffff
+ }
+ }
+ return ${val}
+}
+
+# Proc to do a single-step, and ensure we gently handle
+# an illegal instruction situation.
+proc stepi_over_instruction { xyz } {
+ global gdb_prompt
+ gdb_test_multiple "stepi" "${xyz} " {
+ -re -wrap ".*Illegal instruction.*" {
+ fail "Illegal instruction on single step."
+ return
+ }
+ -re -wrap ".*" {
+ pass "stepi ${xyz}"
+ }
+ }
+}
+
+set check_pc [get_hexadecimal_valueof "\$pc" "default0"]
+
+# set some breakpoints on the instructions below main().
+gdb_test "disas /r main"
+set bp1 *$check_pc+4
+set bp2 *$check_pc+0d12
+set bp3 *$check_pc+0d20
+set bp4 *$check_pc+0d28
+gdb_breakpoint $bp1
+gdb_breakpoint $bp2
+gdb_breakpoint $bp3
+gdb_breakpoint $bp4
+
+# single-step through the plxv instructions, and retrieve the
+# register values as we proceed.
+
+stepi_over_instruction "stepi over NOP"
+stepi_over_instruction "stepi over lnia"
+stepi_over_instruction "stepi over addi"
+
+stepi_over_instruction "stepi over vs4 assignment"
+set check_vs4 [get_vector_hexadecimal_valueof "vs4" "default0"]
+
+stepi_over_instruction "stepi over vs5 assignment"
+set check_vs5 [get_vector_hexadecimal_valueof "vs5" "default0"]
+
+stepi_over_instruction "stepi over vs6 assignment"
+set check_vs6 [get_vector_hexadecimal_valueof "vs6" "default0"]
+
+stepi_over_instruction "stepi over vs7 assignment"
+set check_vs7 [get_vector_hexadecimal_valueof "vs7" "default0"]
+
+set vs4_expected 0xa5b5c5d5a4b4c4d4a3b3c3d3a2b2c2d2
+set vs5_expected 0xa7b7c7d7a6b6c6d6a5b5c5d5a4b4c4d4
+set vs6_expected 0xa9b9c9d9a8b8c8d8a7b7c7d7a6b6c6d6
+set vs7_expected 0xabbbcbdbaabacadaa9b9c9d9a8b8c8d8
+
+if [expr $check_vs4 != $vs4_expected] {
+ fail "unexpected value vs4; actual:$check_vs4 expected:$vs4_expected"
+}
+if [expr $check_vs5 != $vs5_expected ] {
+ fail "unexpected value vs5; actual:$check_vs5 expected:$vs5_expected"
+}
+if [expr $check_vs6 != $vs6_expected ] {
+ fail "unexpected value vs6; actual:$check_vs6 expected:$vs6_expected"
+}
+if [expr $check_vs7 != $vs7_expected ] {
+ fail "unexpected value vs7; actual:$check_vs7 expected:$vs7_expected"
+}
+
+gdb_test "info break"
+gdb_test "info register vs4 vs5 vs6 vs7 "
+gdb_test "disas main #2"
diff --git a/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-plxv-nonrel.s
@@ -0,0 +1,44 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# test to verify that the prefixed instructions that
+# load/store non-relative values work OK.
+
+.global main
+.type main,function
+main:
+ nop
+ lnia 4
+ addi 4,4,40
+ plxv 4,4(4),0
+ plxv 5,12(4),0
+ plxv 6,20(4),0
+ plxv 7,28(4),0
+check_here:
+ blr
+mydata:
+ .long 0xa1b1c1d1 # <<-
+ .long 0xa2b2c2d2 # <<- loaded into vs4
+ .long 0xa3b3c3d3 # <<- loaded into vs4
+ .long 0xa4b4c4d4 # <<- loaded into vs4, vs5
+ .long 0xa5b5c5d5 # <<- loaded into vs4, vs5
+ .long 0xa6b6c6d6 # <<- loaded into vs5, vs6
+ .long 0xa7b7c7d7 # <<- loaded into vs5, vs6
+ .long 0xa8b8c8d8 # <<- loaded into vs6, vs7
+ .long 0xa9b9c9d9 # <<- loaded into vs6, vs7
+ .long 0xaabacada # <<- loaded into vs7
+ .long 0xabbbcbdb # <<- loaded into vs7
+ .long 0xacbcccdc # <<-

View File

@ -0,0 +1,39 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Thu, 6 May 2021 15:39:45 -0400
Subject: gdb-rhbz1870031-p10-prefixed-insn-3of3.patch
;; Backport "Fix build failure for 32-bit targets with..."
;; (Luis Machado, RHBZ 1870031)
commit d9d2ef05f11736bf2e889047cc7588d0c0dd907e
Author: Luis Machado <luis.machado@linaro.org>
Date: Tue Apr 13 09:19:52 2021 -0300
Fix build failure for 32-bit targets with --enable-targets=all
Replace use of %lx with %s.
gdb/ChangeLog:
2021-04-13 Luis Machado <luis.machado@linaro.org>
* rs6000-tdep.c (ppc_displaced_step_fixup): Use %s to print
hex values.
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -982,9 +982,9 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
"displaced: {ppc} addpcis target regnum %d was "
- "0x%lx now 0x%lx",
- regnum, current_val,
- current_val + displaced_offset);
+ "%s now %s",
+ regnum, paddress (gdbarch, current_val),
+ paddress (gdbarch, current_val + displaced_offset));
regcache_cooked_write_unsigned (regs, regnum,
current_val + displaced_offset);
/* point the PC back at the non-displaced instruction. */

View File

@ -37,7 +37,7 @@ Version: 10.2
# The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 5%{?dist}
Release: 6%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
# Do not provide URL for snapshots as the file lasts there only for 2 days.
@ -1154,6 +1154,12 @@ fi
%endif
%changelog
* Mon Jun 28 2021 Keith Seitz <keiths@redhat.com> - 10.2-6.el9
- Backport "PowerPC remove 512 bytes region limit if 2nd DAWR is available"
(Rogerio Alves, RHBZ 1870029)
- Backport patches for "Support prefixed instructions in GDB"
(Will Schmidt and Luis Machado, RHBZ 1870031)
* Fri Jun 25 2021 Keith Seitz <keiths@redhat.com> - 10.2-5.el9
- Backport five patches to support glibc 2.34 with merged libpthread.
(Simon Marchi and Kevin Buettner, RH BZ 1971095)