]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Rewrote riscv-canonicalize-gen.py using xml file
authorTimur Golubovich <timurgol007@gmail.com>
Thu, 4 Sep 2025 18:07:11 +0000 (21:07 +0300)
committertimurgol007 <timurgol007@gmail.com>
Wed, 1 Oct 2025 10:15:36 +0000 (13:15 +0300)
Since catching-syscalls was added, there had been added files containing
syscalls in xml format. As for now riscv-canonicalize-syscall-gen.py uses
glibc for generating, it may be not so comfortable. I changed this
script for reusing newly generated riscv-linux.xml file. Also, I renamed
riscv64_canonicalize_syscall to riscv_linux_canonicalize_syscall as only 64
system is supported in linux. This will simplify the possible further
generalization of this script to other architectures.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
gdb/Makefile.in
gdb/configure.tgt
gdb/riscv-linux-canonicalize-syscall-gen.c [moved from gdb/riscv-canonicalize-syscall-gen.c with 97% similarity]
gdb/riscv-linux-tdep.c
gdb/riscv-linux-tdep.h
gdb/syscalls/riscv-canonicalize-syscall-gen.py [deleted file]
gdb/syscalls/riscv-linux-canonicalize-syscall-gen.py [new file with mode: 0755]

index beacefcfdd551cf878a5c4d4a3a3595633151f64..486d3dbdc5570a68cf2c73e9879a1f4369406bb5 100644 (file)
@@ -769,7 +769,7 @@ ALL_64_TARGET_OBS = \
        mips-sde-tdep.o \
        mips-tdep.o \
        mips64-obsd-tdep.o \
-       riscv-canonicalize-syscall-gen.o \
+       riscv-linux-canonicalize-syscall-gen.o \
        riscv-fbsd-tdep.o \
        riscv-linux-tdep.o \
        riscv-none-tdep.o \
index 34ae50363402521ad0250fc7bf93bb26b2f5927f..fd9036fdd44afba8a8994683e91946d29925050f 100644 (file)
@@ -546,7 +546,7 @@ riscv*-*-freebsd*)
 
 riscv*-*-linux*)
        # Target: Linux/RISC-V
-       gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \
+       gdb_target_obs="riscv-linux-tdep.o riscv-linux-canonicalize-syscall-gen.o \
                        glibc-tdep.o linux-tdep.o solib-svr4.o solib-svr4-linux.o \
                        symfile-mem.o \
                        linux-record.o svr4-tls-tdep.o"
similarity index 97%
rename from gdb/riscv-canonicalize-syscall-gen.c
rename to gdb/riscv-linux-canonicalize-syscall-gen.c
index 67e5410dc6d1f975ec389aad3b124a92c80f6537..9ba8b3f6cf41f354e689bbd5697d7ef2bfccb01c 100644 (file)
@@ -1,4 +1,4 @@
-/* DO NOT EDIT: Autogenerated by riscv-canonicalize-syscall-gen.py
+/* DO NOT EDIT: Autogenerated by riscv-linux-canonicalize-syscall-gen.py
 
    Copyright (C) 2024-2025 Free Software Foundation, Inc.
 
 #include "defs.h"
 #include "riscv-linux-tdep.h"
 
-/* riscv64_canonicalize_syscall maps from the native riscv 64 Linux set
+/* riscv_linux_canonicalize_syscall maps from the native RISC-V Linux set
    of syscall ids into a canonical set of syscall ids used by
    process record.  */
 
 enum gdb_syscall
-riscv64_canonicalize_syscall (int syscall)
+riscv_linux_canonicalize_syscall (int syscall)
 {
   switch (syscall)
     {
@@ -352,6 +352,9 @@ riscv64_canonicalize_syscall (int syscall)
     /* case 464: return gdb_sys_getxattrat;  */
     /* case 465: return gdb_sys_listxattrat;  */
     /* case 466: return gdb_sys_removexattrat;  */
+    /* case 467: return gdb_sys_open_tree_attr;  */
+    /* case 468: return gdb_sys_file_getattr;  */
+    /* case 469: return gdb_sys_file_setattr;  */
     default:
       return gdb_sys_no_syscall;
     }
index 0a946111b9d2bfd9333ecca6fcc93d005107144e..05f92f832eb23a20644c0324345696890c1321c2 100644 (file)
@@ -230,7 +230,7 @@ riscv_linux_syscall_record (struct regcache *regcache,
 {
   gdb_assert (regcache != nullptr);
 
-  enum gdb_syscall syscall_gdb = riscv64_canonicalize_syscall (svc_number);
+  enum gdb_syscall syscall_gdb = riscv_linux_canonicalize_syscall (svc_number);
 
   if (record_debug > 1)
     gdb_printf (gdb_stdlog, "Made syscall %s.\n", plongest (svc_number));
@@ -261,12 +261,11 @@ riscv_linux_syscall_record (struct regcache *regcache,
   return 0;
 }
 
-/* Initialize the riscv64_linux_record_tdep.  */
+/* Initialize the riscv_linux_record_tdep.  */
 
 static void
-riscv64_linux_record_tdep_init (struct gdbarch *gdbarch,
-                               struct linux_record_tdep &
-                               riscv_linux_record_tdep)
+riscv_linux_record_tdep_init (struct gdbarch *gdbarch,
+                             struct linux_record_tdep &riscv_linux_record_tdep)
 {
   gdb_assert (gdbarch != nullptr);
 
@@ -561,7 +560,7 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->syscall_next_pc = riscv_linux_syscall_next_pc;
   tdep->riscv_syscall_record = riscv_linux_syscall_record;
 
-  riscv64_linux_record_tdep_init (gdbarch, riscv_linux_record_tdep);
+  riscv_linux_record_tdep_init (gdbarch, riscv_linux_record_tdep);
 
   /* Functions for 'catch syscall'.  */
   set_gdbarch_xml_syscall_file (gdbarch, "syscalls/riscv-linux.xml");
index 9dd9e373caabb812b3cb65b05bc9945a287d6cb2..9f0d95bbe8e60bf4a9955934fb3479ef1914e4cc 100644 (file)
 
 #include "linux-record.h"
 
-/* riscv64_canonicalize_syscall maps from the native riscv Linux set
-   of syscall ids into a canonical set of syscall ids used by
+/* riscv_linux_canonicalize_syscall maps from the native riscv Linux
+   set of syscall ids into a canonical set of syscall ids used by
    process record.  */
 
-extern enum gdb_syscall riscv64_canonicalize_syscall (int syscall);
+extern enum gdb_syscall riscv_linux_canonicalize_syscall (int syscall);
 
 #endif /* GDB_RISCV_LINUX_TDEP_H */
diff --git a/gdb/syscalls/riscv-canonicalize-syscall-gen.py b/gdb/syscalls/riscv-canonicalize-syscall-gen.py
deleted file mode 100755 (executable)
index 40039bb..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env python3
-# pylint: disable=invalid-name
-
-# Copyright (C) 2024-2025 Free Software Foundation, Inc.
-# Contributed by Timur Golubovich
-
-# This file is part of GDB.
-
-# 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/>.
-
-
-# To get help message for this script, run:
-# ./gdb/syscalls/riscv-canonicalize-syscall-gen.py --help
-
-# Execution result:
-
-# usage: riscv-canonicalize-syscall-gen.py [-h] -i INPUT
-#
-# Generate file gdb/riscv-canonicalize-syscall-gen.c from path to riscv linux syscalls.
-#
-# options:
-#   -h, --help            show this help message and exit
-#   -i INPUT, --input INPUT
-#                         path to riscv linux syscalls (glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)
-
-import argparse
-import re
-import sys
-from pathlib import Path as _Path
-
-head = """\
-/* DO NOT EDIT: Autogenerated by riscv-canonicalize-syscall-gen.py
-
-   Copyright (C) 2024-2025 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   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/>.  */
-
-#include "defs.h"
-#include "riscv-linux-tdep.h"
-
-/* riscv64_canonicalize_syscall maps from the native riscv 64 Linux set
-   of syscall ids into a canonical set of syscall ids used by
-   process record.  */
-
-enum gdb_syscall
-riscv64_canonicalize_syscall (int syscall)
-{
-  switch (syscall)
-    {
-"""
-
-tail = """\
-    default:
-      return gdb_sys_no_syscall;
-    }
-}
-"""
-
-
-class Generator:
-    def _get_gdb_syscalls(self, gdb_syscalls_path: _Path) -> list[str]:
-        gdb_syscalls: list[str] = []
-        with open(gdb_syscalls_path, "r", encoding="UTF-8") as file:
-            lines = file.readlines()
-            for line in lines:
-                match = re.search(r"\s*(?P<name>gdb_sys_[^S]+)\S*=", line)
-                if match:
-                    gdb_syscalls.append(match.group("name").strip())
-        return gdb_syscalls
-
-    def _get_canon_syscalls_lines(
-        self, syscalls_path: _Path, gdb_syscalls: list[str]
-    ) -> list[str]:
-        canon_syscalls: dict[int, str] = {}
-        with open(syscalls_path, "r", encoding="UTF-8") as file:
-            lines = file.readlines()
-            for line in lines:
-                match = re.match(
-                    r"#define\s+__NR_(?P<name>[^\s]+)\s+(?P<number>\d+)", line
-                )
-                if match:
-                    syscall_name = match.group("name")
-                    syscall_num = int(match.group("number"))
-                    gdb_syscall_name = f"gdb_sys_{syscall_name}"
-                    if gdb_syscall_name in gdb_syscalls:
-                        value = f"    case {syscall_num}: return {gdb_syscall_name};\n"
-                        canon_syscalls[syscall_num] = value
-                    # this is a place for corner cases
-                    elif syscall_name == "mmap":
-                        gdb_old_syscall_name = "gdb_sys_old_mmap"
-                        value = (
-                            f"    case {syscall_num}: return {gdb_old_syscall_name};\n"
-                        )
-                        canon_syscalls[syscall_num] = value
-                    else:
-                        value = f"    /* case {syscall_num}: return {gdb_syscall_name};  */\n"
-                        canon_syscalls[syscall_num] = value
-        return [canon_syscalls[syscall_num] for syscall_num in sorted(canon_syscalls)]
-
-    def generate(self, syscalls_path: _Path) -> None:
-        repo_path = _Path(__file__).parent.parent.parent
-        gdb_syscalls_path = repo_path / "gdb" / "linux-record.h"
-        canon_syscalls_path = repo_path / "gdb" / "riscv-canonicalize-syscall-gen.c"
-
-        gdb_syscalls = self._get_gdb_syscalls(gdb_syscalls_path)
-        canon_syscalls_lines = self._get_canon_syscalls_lines(
-            syscalls_path, gdb_syscalls
-        )
-
-        with open(canon_syscalls_path, "w", encoding="UTF-8") as file:
-            file.writelines(head)
-            file.writelines(canon_syscalls_lines)
-            file.writelines(tail)
-
-
-help_message = """\
-Generate file gdb/riscv-canonicalize-syscall-gen.c
-from path to riscv linux syscalls.
-"""
-
-
-def setup_parser() -> argparse.ArgumentParser:
-    parser = argparse.ArgumentParser(description=help_message)
-    parser.add_argument(
-        "-i",
-        "--input",
-        type=_Path,
-        required=True,
-        help="path to riscv linux syscalls (glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)",
-    )
-    return parser
-
-
-def main(argv: list[str]) -> int:
-    try:
-        parser = setup_parser()
-        args = parser.parse_args(argv)
-        generator = Generator()
-        generator.generate(args.input)
-        return 0
-    except RuntimeError as e:
-        print(str(e))
-        return -1
-
-
-if __name__ == "__main__":
-    sys.exit(main(sys.argv[1:]))
diff --git a/gdb/syscalls/riscv-linux-canonicalize-syscall-gen.py b/gdb/syscalls/riscv-linux-canonicalize-syscall-gen.py
new file mode 100755 (executable)
index 0000000..aaf3943
--- /dev/null
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2024-2025 Free Software Foundation, Inc.
+# Contributed by Timur Golubovich
+
+# This file is part of GDB.
+
+# 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/>.
+
+
+# To get help message for this script, run:
+# ./gdb/syscalls/riscv-linux-canonicalize-syscall-gen.py --help
+
+# Execution result:
+
+# usage: riscv-linux-canonicalize-syscall-gen.py [-h]
+#
+# Generate file gdb/riscv-linux-canonicalize-syscall-gen.c from
+# gdb/syscalls/riscv-linux.xml.
+#
+# options:
+#   -h, --help            show this help message and exit
+
+import argparse
+import re
+import xml.etree.ElementTree as ET
+from pathlib import Path
+
+FILE = Path(__file__).resolve()
+
+HEAD = f"""\
+/* DO NOT EDIT: Autogenerated by {FILE.name}
+
+   Copyright (C) 2024-2025 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "defs.h"
+#include "riscv-linux-tdep.h"
+
+/* riscv_linux_canonicalize_syscall maps from the native RISC-V Linux set
+   of syscall ids into a canonical set of syscall ids used by
+   process record.  */
+
+enum gdb_syscall
+riscv_linux_canonicalize_syscall (int syscall)
+{{
+  switch (syscall)
+    {{
+"""
+
+TAIL = """\
+    default:
+      return gdb_sys_no_syscall;
+    }
+}
+"""
+
+HELP_MESSAGE = """\
+Generate file gdb/riscv-linux-canonicalize-syscall-gen.c from
+gdb/syscalls/riscv-linux.xml.
+"""
+
+
+class Generator:
+    def _get_gdb_syscalls(self, gdb_syscalls_path: Path) -> set[str]:
+        gdb_syscalls = set[str]()
+        with open(gdb_syscalls_path, "r", encoding="UTF-8") as file:
+            for line in file:
+                match = re.search(r"(gdb_sys_\S+)\s*=", line)
+                if match:
+                    gdb_syscalls.add(match[1].strip())
+        return gdb_syscalls
+
+    def _get_arch_syscalls(self, xml_syscalls_path: Path) -> dict[str, int]:
+        arch_syscalls: dict[str, int] = {}
+        syscalls_info = ET.parse(xml_syscalls_path)
+        for syscall in syscalls_info.findall("syscall"):
+            sysname = syscall.attrib["name"]
+            sysno = int(syscall.attrib["number"])
+            arch_syscalls[sysname] = sysno
+        return arch_syscalls
+
+    def _get_canon_syscalls_lines(
+        self,
+        arch_syscalls: dict[str, int],
+        gdb_syscalls: set[str],
+        exceptions: dict[str, str],
+    ) -> list[str]:
+        canon_syscalls: dict[int, str] = {}
+        for sysname, sysno in arch_syscalls.items():
+            if sysname in exceptions:
+                sysname = exceptions[sysname]
+            gdb_sysname = f"gdb_sys_{sysname}"
+            value = f"    /* case {sysno}: return {gdb_sysname};  */\n"
+            if gdb_sysname in gdb_syscalls:
+                value = f"    case {sysno}: return {gdb_sysname};\n"
+            canon_syscalls[sysno] = value
+        return [canon_syscalls[sysno] for sysno in sorted(canon_syscalls)]
+
+    def generate(self) -> None:
+        repo_path = FILE.parent.parent.parent
+        gdb_path = repo_path / "gdb"
+        xml_syscalls_path = gdb_path / "syscalls" / "riscv-linux.xml"
+        gdb_syscalls_path = gdb_path / "linux-record.h"
+        arch_syscalls_path = gdb_path / "riscv-linux-canonicalize-syscall-gen.c"
+        exceptions = {"mmap": "old_mmap"}
+
+        arch_syscalls = self._get_arch_syscalls(xml_syscalls_path)
+        gdb_syscalls = self._get_gdb_syscalls(gdb_syscalls_path)
+        canon_syscalls_lines = self._get_canon_syscalls_lines(
+            arch_syscalls, gdb_syscalls, exceptions
+        )
+
+        with open(arch_syscalls_path, "w", encoding="UTF-8") as file:
+            file.writelines(HEAD)
+            file.writelines(canon_syscalls_lines)
+            file.writelines(TAIL)
+
+
+def main() -> int:
+    parser = argparse.ArgumentParser(description=HELP_MESSAGE)
+    parser.parse_args()
+    Generator().generate()
+    return 0
+
+
+if __name__ == "__main__":
+    main()