From: Timur Golubovich Date: Thu, 28 Aug 2025 17:12:55 +0000 (+0300) Subject: This commit adds support for catching syscalls on riscv X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=52bb1ca383ee2765332aee3023650ccba895a8ac;p=thirdparty%2Fbinutils-gdb.git This commit adds support for catching syscalls on riscv It affects following files: - gdb/riscv-linux-tdep.c: a function to get syscall number. - gdbserver/linux-riscv-low.cc: syscall trapinfo function to enable catching syscalls on remote targets. - gdb/syscalls/riscv-linux.xml.in: a file with syscalls, generated from linux kernel sources using gdb/syscalls/update-linux-from-src.sh script. - gdb/syscalls/riscv-linux.xml: a file with syscalls, patched with group names gdb/syscalls/apply-defaults.xsl using xsltproc tool. - gdb/syscalls/update-linux.sh: set startyear to 2025 on riscv. - gdb/syscalls/update-linux-from-src.sh: riscv syscall table must be generated from kernel headers. - gdb/NEWS: catch-syscall feature is now available on riscv. - gdb/data-directory/Makefile.in: adding file with syscalls to Makefile. Approved-By: Tom Tromey --- 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