You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
633 lines
22 KiB
633 lines
22 KiB
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 # <<-
|
|
|