aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/riscv-tdep.c8
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li-foo.s47
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.c29
-rw-r--r--gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.exp42
4 files changed, 124 insertions, 2 deletions
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index d01ba9b..144eb7e 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1562,6 +1562,7 @@ public:
ADDW,
AUIPC,
LUI,
+ LI,
SD,
SW,
LD,
@@ -1943,6 +1944,8 @@ riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
m_rd = decode_register_index (ival, OP_SH_CRS1S);
m_imm.s = EXTRACT_CITYPE_LUI_IMM (ival);
}
+ else if (is_c_li_insn (ival))
+ decode_ci_type_insn (LI, ival);
/* C_SD and C_FSW have the same opcode. C_SD is RV64 and RV128 only,
and C_FSW is RV32 only. */
else if (xlen != 4 && is_c_sd_insn (ival))
@@ -2302,10 +2305,11 @@ riscv_scan_prologue (struct gdbarch *gdbarch,
gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
regs[insn.rd ()] = pv_constant (cur_pc + insn.imm_signed ());
}
- else if (insn.opcode () == riscv_insn::LUI)
+ else if (insn.opcode () == riscv_insn::LUI
+ || insn.opcode () == riscv_insn::LI)
{
/* Handle: lui REG, n
- Where REG is not gp register. */
+ or: li REG, n */
gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
regs[insn.rd ()] = pv_constant (insn.imm_signed ());
}
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li-foo.s b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li-foo.s
new file mode 100644
index 0000000..787aacd
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li-foo.s
@@ -0,0 +1,47 @@
+/* Copyright 2023 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/>. */
+
+
+/* Simple asm function that makes use of c.li and c.lui in the
+ function prologue before the return address and frame pointers are
+ written the stack. This ensures that GDB's prologue unwinder can
+ understand these instructions. */
+
+ .option pic
+ .text
+
+ .globl foo
+ .type foo, @function
+foo:
+ addi sp,sp,-32
+ sd s1,8(sp)
+
+ c.li s1,-4
+ c.lui s1,4
+
+ sd fp,24(sp)
+ sd ra,16(sp)
+ addi fp,sp,32
+
+ call bar@plt
+
+ ld s1,8(sp)
+ ld ra,16(sp)
+ ld fp,24(sp)
+ addi sp,sp,32
+ jr ra
+
+ .size foo, .-foo
+ .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.c b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.c
new file mode 100644
index 0000000..d3a0cb3
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.c
@@ -0,0 +1,29 @@
+/* Copyright 2023 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-c_li-asm.s. */
+extern int foo (void);
+
+int
+bar (void)
+{
+ return 0;
+}
+
+int
+main (void)
+{
+ return foo ();
+}
diff --git a/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.exp b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.exp
new file mode 100644
index 0000000..069effa
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.exp
@@ -0,0 +1,42 @@
+# Copyright 2023 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 compressed 'c.li'
+# instruction in its prologue.
+
+require {istarget "riscv64-*-*"}
+
+standard_testfile .c -foo.s
+
+if {[prepare_for_testing "failed to prepare" $testfile \
+ "$srcfile $srcfile2" nodebug]} {
+ return -1
+}
+
+if {![runto_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"