diff options
-rw-r--r-- | gdb/riscv-tdep.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li-foo.s | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.c | 29 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/riscv64-unwind-prologue-with-c_li.exp | 42 |
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" |