diff --git a/gdb/NEWS b/gdb/NEWS
index 8be367d2424..b632cde7e0d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -96,6 +96,8 @@ single-inf-arg in qSupported
translation mode of its stdout/stderr to binary mode. This disables
Line Feed translation. MS-Windows only.
+* The "catch syscall" command now works on riscv*-linux* targets.
+
* New commands
maintenance check psymtabs
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
index 2ca2b8e7e5f..d7f4c988fb6 100644
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -61,6 +61,7 @@ GEN_SYSCALLS_FILES = \
mips-o32-linux.xml \
ppc-linux.xml \
ppc64-linux.xml \
+ riscv-linux.xml \
s390-linux.xml \
s390x-linux.xml \
sparc-linux.xml \
diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index 982273a0b9d..0a946111b9d 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -502,6 +502,28 @@ riscv_linux_get_tls_dtp_offset (struct gdbarch *gdbarch, ptid_t ptid,
return 0;
}
+/* Function to extract syscall number. */
+
+static LONGEST
+riscv_linux_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
+{
+ struct regcache *regcache = get_thread_regcache (thread);
+ LONGEST ret;
+
+ /* Getting the system call number from the register.
+ When dealing with riscv architecture, this information
+ is stored in $a7 register. */
+ if (regcache->cooked_read (RISCV_A7_REGNUM, &ret)
+ != register_status::REG_VALID)
+ {
+ warning (_ ("Can not read a7 register"));
+ return -1;
+ }
+
+ /* The result. */
+ return ret;
+}
+
/* Initialize RISC-V Linux ABI info. */
static void
@@ -540,6 +562,10 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->riscv_syscall_record = riscv_linux_syscall_record;
riscv64_linux_record_tdep_init (gdbarch, riscv_linux_record_tdep);
+
+ /* Functions for 'catch syscall'. */
+ set_gdbarch_xml_syscall_file (gdbarch, "syscalls/riscv-linux.xml");
+ set_gdbarch_get_syscall_number (gdbarch, riscv_linux_get_syscall_number);
}
/* Initialize RISC-V Linux target support. */
diff --git a/gdb/syscalls/riscv-linux.xml b/gdb/syscalls/riscv-linux.xml
new file mode 100644
index 00000000000..3578c3fcce5
--- /dev/null
+++ b/gdb/syscalls/riscv-linux.xml
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/syscalls/riscv-linux.xml.in b/gdb/syscalls/riscv-linux.xml.in
new file mode 100644
index 00000000000..17b2b0ae2de
--- /dev/null
+++ b/gdb/syscalls/riscv-linux.xml.in
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdb/syscalls/update-linux-from-src.sh b/gdb/syscalls/update-linux-from-src.sh
index ea06c133242..26c38f6c531 100755
--- a/gdb/syscalls/update-linux-from-src.sh
+++ b/gdb/syscalls/update-linux-from-src.sh
@@ -325,6 +325,11 @@ regen ()
gen_from_kernel_headers "$f" arm64
return
;;
+ riscv-linux.xml.in)
+ # No syscall.tbl.
+ gen_from_kernel_headers "$f" riscv
+ return
+ ;;
arm-linux.xml.in)
t="arch/arm/tools/syscall.tbl"
h="arch/arm/include/uapi/asm/unistd.h"
diff --git a/gdb/syscalls/update-linux.sh b/gdb/syscalls/update-linux.sh
index 107ce05b4e8..cbc8a9d82d5 100755
--- a/gdb/syscalls/update-linux.sh
+++ b/gdb/syscalls/update-linux.sh
@@ -40,6 +40,9 @@ case "$f" in
*aarch64-linux.xml.in)
startyear=2015
;;
+ *riscv-linux.xml.in)
+ startyear=2025
+ ;;
esac
year=$(date +%Y)
diff --git a/gdbserver/linux-riscv-low.cc b/gdbserver/linux-riscv-low.cc
index 8c742f406a2..f70ed597051 100644
--- a/gdbserver/linux-riscv-low.cc
+++ b/gdbserver/linux-riscv-low.cc
@@ -58,6 +58,10 @@ protected:
void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
bool low_breakpoint_at (CORE_ADDR pc) override;
+
+ bool low_supports_catch_syscall () override;
+
+ void low_get_syscall_trapinfo (regcache *regcache, int *sysno) override;
};
/* The singleton target ops object. */
@@ -78,6 +82,26 @@ riscv_target::low_cannot_store_register (int regno)
"is not implemented by the target");
}
+/* Implementation of linux target ops method "low_supports_catch_syscall". */
+
+bool
+riscv_target::low_supports_catch_syscall ()
+{
+ return true;
+}
+
+/* Implementation of linux target ops method "low_get_syscall_trapinfo". */
+
+void
+riscv_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno)
+{
+ LONGEST l_sysno;
+
+ /* The content of a register. */
+ collect_register_by_name (regcache, "a7", &l_sysno);
+ *sysno = (int)l_sysno;
+}
+
/* Implementation of linux target ops method "low_arch_setup". */
void