aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/riscv-tdep.c13
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.c29
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.exp44
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.s47
4 files changed, 132 insertions, 1 deletions
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 8b55bc3..b8844b6 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1411,6 +1411,7 @@ public:
SW,
LD,
LW,
+ MV,
/* These are needed for software breakpoint support. */
JAL,
JALR,
@@ -1789,9 +1790,11 @@ riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
else if (xlen != 4 && is_c_sdsp_insn (ival))
decode_css_type_insn (SD, ival, EXTRACT_CSSTYPE_SDSP_IMM (ival));
/* C_JR and C_MV have the same opcode. If RS2 is 0, then this is a C_JR.
- So must try to match C_JR first as it ahs more bits in mask. */
+ So must try to match C_JR first as it has more bits in mask. */
else if (is_c_jr_insn (ival))
decode_cr_type_insn (JALR, ival);
+ else if (is_c_mv_insn (ival))
+ decode_cr_type_insn (MV, ival);
else if (is_c_j_insn (ival))
decode_cj_type_insn (JAL, ival);
else if (is_c_beqz_insn (ival))
@@ -1964,6 +1967,14 @@ riscv_scan_prologue (struct gdbarch *gdbarch,
insn.imm_signed ()),
(insn.opcode () == riscv_insn::LW ? 4 : 8));
}
+ else if (insn.opcode () == riscv_insn::MV)
+ {
+ /* Handle: c.mv RD, RS2 */
+ gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
+ gdb_assert (insn.rs2 () < RISCV_NUM_INTEGER_REGS);
+ gdb_assert (insn.rs2 () > 0);
+ regs[insn.rd ()] = regs[insn.rs2 ()];
+ }
else
{
end_prologue_addr = cur_pc;
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.c b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.c
new file mode 100644
index 0000000..bb8a8ee
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.c
@@ -0,0 +1,29 @@
+/* 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/>. */
+
+/* See riscv64-unwind-prologue-with-mv.s for implementation. */
+
+extern int bar ();
+
+/* See riscv64-unwind-prologue-with-mv.s for implementation. */
+
+extern int foo ();
+
+int
+main ()
+{
+ return foo ();
+}
+
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.exp b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.exp
new file mode 100644
index 0000000..47429ba
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.exp
@@ -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/>.
+
+# This tests GDB's ability to use the RISC-V prologue scanner in order to
+# unwind through a function that uses the 'c.mv' instruction in its prologue.
+
+if {![istarget "riscv64-*-*"]} {
+ verbose "Skipping ${gdb_test_file_name}."
+ return
+}
+
+standard_testfile .c .s
+if {[prepare_for_testing "failed to prepare" $testfile \
+ "$srcfile $srcfile2" nodebug]} {
+ return -1
+}
+
+if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+}
+
+gdb_breakpoint "bar"
+gdb_continue_to_breakpoint "bar"
+gdb_test "bt" \
+ [multi_line \
+ "#0\[ \t\]*$hex in bar \\\(\\\)" \
+ "#1\[ \t\]*$hex in foo \\\(\\\)" \
+ "#2\[ \t\]*$hex in main \\\(\\\)"] \
+ "Backtrace to the main frame"
+gdb_test "finish" "foo \\\(\\\)" "finish bar"
+gdb_test "finish" "main \\\(\\\)" "finish foo"
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.s b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.s
new file mode 100644
index 0000000..a1ec538
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-mv.s
@@ -0,0 +1,47 @@
+/* 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/>. */
+
+/* This testcase contains a function where the 'c.mv' instruction is used in
+ the prologue.
+
+ The following functions are roughly equivalent to the following C code (with
+ prologue crafted to contain the c.mv instruction):
+
+ int bar () { return 0; }
+ int foo () { return bar (); } */
+
+ .option pic
+ .text
+ .align 1
+ .globl bar
+ .type bar, @function
+bar:
+ li a0,0
+ jr ra
+ .size bar, .-bar
+
+ .align 1
+ .globl foo
+ .type foo, @function
+foo:
+ addi sp,sp,-32
+ c.mv t3,ra
+ sd t3,8(sp)
+ call bar
+ ld t3,8(sp)
+ mv ra,t3
+ addi sp,sp,32
+ jr ra
+ .size foo, .-foo