diff options
author | Lancelot SIX <lsix@lancelotsix.com> | 2021-07-16 22:10:08 +0000 |
---|---|---|
committer | Lancelot SIX <lsix@lancelotsix.com> | 2021-07-16 22:10:08 +0000 |
commit | e843807b2df9f99b8172bfaf4daa3a42461cdbfa (patch) | |
tree | fdce54aa31c1f7bb740dc766c5d7bc13d0428299 /gdb/riscv-tdep.c | |
parent | 47357fdc1db04240be98c683de776b3a351e945b (diff) | |
download | fsf-binutils-gdb-e843807b2df9f99b8172bfaf4daa3a42461cdbfa.zip fsf-binutils-gdb-e843807b2df9f99b8172bfaf4daa3a42461cdbfa.tar.gz fsf-binutils-gdb-e843807b2df9f99b8172bfaf4daa3a42461cdbfa.tar.bz2 |
gdb: Support stepping out from signal handler on riscv*-linux
Currently, gdb cannot step outside of a signal handler on RISC-V
platforms. This causes multiple failures in gdb.base/sigstep.exp:
FAIL: gdb.base/sigstep.exp: continue to handler, nothing in handler, step from handler: leave handler (timeout)
FAIL: gdb.base/sigstep.exp: continue to handler, si+advance in handler, step from handler: leave handler (timeout)
FAIL: gdb.base/sigstep.exp: continue to handler, nothing in handler, next from handler: leave handler (timeout)
FAIL: gdb.base/sigstep.exp: continue to handler, si+advance in handler, next from handler: leave handler (timeout)
FAIL: gdb.base/sigstep.exp: stepi from handleri: leave signal trampoline
FAIL: gdb.base/sigstep.exp: nexti from handleri: leave signal trampoline
=== gdb Summary ===
# of expected passes 587
# of unexpected failures 6
This patch adds support for stepping outside of a signal handler on
riscv*-*-linux*.
Implementation is heavily inspired from mips_linux_syscall_next_pc and
surroundings as advised by Pedro Alves.
After this patch, all tests in gdb.base/sigstep.exp pass.
Build and tested on riscv64-linux-gnu.
Diffstat (limited to 'gdb/riscv-tdep.c')
-rw-r--r-- | gdb/riscv-tdep.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 19e2616..b5b0d2d 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -1421,6 +1421,8 @@ public: /* These are needed for stepping over atomic sequences. */ LR, SC, + /* This instruction is used to do a syscall. */ + ECALL, /* Other instructions are not interesting during the prologue scan, and are ignored. */ @@ -1711,6 +1713,8 @@ riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc) decode_r_type_insn (SC, ival); else if (is_sc_d_insn (ival)) decode_r_type_insn (SC, ival); + else if (is_ecall_insn (ival)) + decode_i_type_insn (ECALL, ival); else /* None of the other fields are valid in this case. */ m_opcode = OTHER; @@ -3764,6 +3768,7 @@ static CORE_ADDR riscv_next_pc (struct regcache *regcache, CORE_ADDR pc) { struct gdbarch *gdbarch = regcache->arch (); + const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct riscv_insn insn; CORE_ADDR next_pc; @@ -3826,6 +3831,11 @@ riscv_next_pc (struct regcache *regcache, CORE_ADDR pc) if (src1 >= src2) next_pc = pc + insn.imm_signed (); } + else if (insn.opcode () == riscv_insn::ECALL) + { + if (tdep->syscall_next_pc != nullptr) + next_pc = tdep->syscall_next_pc (get_current_frame ()); + } return next_pc; } |