diff --git a/0001-test.patch b/0001-test.patch new file mode 100644 index 0000000000000000000000000000000000000000..bec70b21aa709e86579d08550122cc0c24587a23 --- /dev/null +++ b/0001-test.patch @@ -0,0 +1,878 @@ +From 32b12128c8edbfb0579ec7bc20f331fca5f1a77a Mon Sep 17 00:00:00 2001 +From: zhuyunfei +Date: Tue, 10 Dec 2024 16:30:35 +0800 +Subject: [PATCH] test + +--- + gdb/arch/loongarch.c | 6 ++ + gdb/arch/loongarch.h | 4 + + gdb/features/Makefile | 2 + + gdb/features/loongarch/lasx.c | 85 ++++++++++++++++++++ + gdb/features/loongarch/lasx.xml | 60 ++++++++++++++ + gdb/features/loongarch/lsx.c | 82 +++++++++++++++++++ + gdb/features/loongarch/lsx.xml | 59 ++++++++++++++ + gdb/loongarch-linux-nat.c | 123 +++++++++++++++++++++++++++++ + gdb/loongarch-linux-tdep.c | 130 +++++++++++++++++++++++++++++++ + gdb/loongarch-tdep.c | 75 ++++++++++++++++++ + gdb/loongarch-tdep.h | 2 + + gdbserver/linux-loongarch-low.cc | 52 +++++++++++++ + 12 files changed, 680 insertions(+) + create mode 100644 gdb/features/loongarch/lasx.c + create mode 100644 gdb/features/loongarch/lasx.xml + create mode 100644 gdb/features/loongarch/lsx.c + create mode 100644 gdb/features/loongarch/lsx.xml + +diff --git a/gdb/arch/loongarch.c b/gdb/arch/loongarch.c +index 168fcbc..56767f1 100644 +--- a/gdb/arch/loongarch.c ++++ b/gdb/arch/loongarch.c +@@ -25,6 +25,8 @@ + #include "../features/loongarch/base32.c" + #include "../features/loongarch/base64.c" + #include "../features/loongarch/fpu.c" ++#include "../features/loongarch/lsx.c" ++#include "../features/loongarch/lasx.c" + + #ifndef GDBSERVER + #define STATIC_IN_GDB static +@@ -63,6 +65,10 @@ loongarch_create_target_description (const struct loongarch_gdbarch_features fea + /* For now we only support creating single float and double float. */ + regnum = create_feature_loongarch_fpu (tdesc.get (), regnum); + ++ /* For now we only support creating lsx and lasx. */ ++ regnum = create_feature_loongarch_lsx (tdesc.get (), regnum); ++ regnum = create_feature_loongarch_lasx (tdesc.get (), regnum); ++ + return tdesc; + } + +diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h +index d0a63dc..48662af 100644 +--- a/gdb/arch/loongarch.h ++++ b/gdb/arch/loongarch.h +@@ -41,6 +41,10 @@ enum loongarch_regnum + LOONGARCH_FIRST_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + LOONGARCH_LINUX_NUM_FPREGSET, + LOONGARCH_LINUX_NUM_FCC = 8, + LOONGARCH_FCSR_REGNUM = LOONGARCH_FIRST_FCC_REGNUM + LOONGARCH_LINUX_NUM_FCC, ++ LOONGARCH_FIRST_LSX_REGNUM = LOONGARCH_FCSR_REGNUM + 1, ++ LOONGARCH_LINUX_NUM_LSXREGSET = 32, ++ LOONGARCH_FIRST_LASX_REGNUM = LOONGARCH_FIRST_LSX_REGNUM + LOONGARCH_LINUX_NUM_LSXREGSET, ++ LOONGARCH_LINUX_NUM_LASXREGSET = 32, + }; + + enum loongarch_fputype +diff --git a/gdb/features/Makefile b/gdb/features/Makefile +index 32341f7..965e32d 100644 +--- a/gdb/features/Makefile ++++ b/gdb/features/Makefile +@@ -237,6 +237,8 @@ FEATURE_XMLFILES = aarch64-core.xml \ + loongarch/base32.xml \ + loongarch/base64.xml \ + loongarch/fpu.xml \ ++ loongarch/lsx.xml \ ++ loongarch/lasx.xml \ + riscv/rv32e-xregs.xml \ + riscv/32bit-cpu.xml \ + riscv/32bit-fpu.xml \ +diff --git a/gdb/features/loongarch/lasx.c b/gdb/features/loongarch/lasx.c +new file mode 100644 +index 0000000..52d486e +--- /dev/null ++++ b/gdb/features/loongarch/lasx.c +@@ -0,0 +1,85 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: lasx.xml */ ++ ++#include "gdbsupport/tdesc.h" ++ ++static int ++create_feature_loongarch_lasx (struct target_desc *result, long regnum) ++{ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.loongarch.lasx"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v8f32", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "ieee_double"); ++ tdesc_create_vector (feature, "v4f64", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v32i8", element_type, 32); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v16i16", element_type, 16); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v8i32", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int64"); ++ tdesc_create_vector (feature, "v4i64", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "uint128"); ++ tdesc_create_vector (feature, "v2ui128", element_type, 2); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "lasxv"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "v8f32"); ++ tdesc_add_field (type_with_fields, "v8_float", field_type); ++ field_type = tdesc_named_type (feature, "v4f64"); ++ tdesc_add_field (type_with_fields, "v4_double", field_type); ++ field_type = tdesc_named_type (feature, "v32i8"); ++ tdesc_add_field (type_with_fields, "v32_int8", field_type); ++ field_type = tdesc_named_type (feature, "v16i16"); ++ tdesc_add_field (type_with_fields, "v16_int16", field_type); ++ field_type = tdesc_named_type (feature, "v8i32"); ++ tdesc_add_field (type_with_fields, "v8_int32", field_type); ++ field_type = tdesc_named_type (feature, "v4i64"); ++ tdesc_add_field (type_with_fields, "v4_int64", field_type); ++ field_type = tdesc_named_type (feature, "v2ui128"); ++ tdesc_add_field (type_with_fields, "v2_uint128", field_type); ++ ++ tdesc_create_reg (feature, "xr0", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr1", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr2", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr3", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr4", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr5", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr6", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr7", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr8", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr9", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr10", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr11", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr12", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr13", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr14", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr15", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr16", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr17", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr18", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr19", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr20", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr21", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr22", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr23", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr24", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr25", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr26", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr27", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr28", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr29", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr30", regnum++, 1, "lasx", 256, "lasxv"); ++ tdesc_create_reg (feature, "xr31", regnum++, 1, "lasx", 256, "lasxv"); ++ return regnum; ++} +diff --git a/gdb/features/loongarch/lasx.xml b/gdb/features/loongarch/lasx.xml +new file mode 100644 +index 0000000..753b982 +--- /dev/null ++++ b/gdb/features/loongarch/lasx.xml +@@ -0,0 +1,60 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/loongarch/lsx.c b/gdb/features/loongarch/lsx.c +new file mode 100644 +index 0000000..0067c2f +--- /dev/null ++++ b/gdb/features/loongarch/lsx.c +@@ -0,0 +1,82 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: lsx.xml */ ++ ++#include "gdbsupport/tdesc.h" ++ ++static int ++create_feature_loongarch_lsx (struct target_desc *result, long regnum) ++{ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.loongarch.lsx"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "ieee_double"); ++ tdesc_create_vector (feature, "v2f64", element_type, 2); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int64"); ++ tdesc_create_vector (feature, "v2i64", element_type, 2); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "lsxv"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "v4f32"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v2f64"); ++ tdesc_add_field (type_with_fields, "v2_double", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v2i64"); ++ tdesc_add_field (type_with_fields, "v2_int64", field_type); ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ ++ tdesc_create_reg (feature, "vr0", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr1", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr2", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr3", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr4", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr5", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr6", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr7", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr8", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr9", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr10", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr11", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr12", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr13", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr14", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr15", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr16", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr17", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr18", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr19", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr20", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr21", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr22", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr23", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr24", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr25", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr26", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr27", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr28", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr29", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr30", regnum++, 1, "lsx", 128, "lsxv"); ++ tdesc_create_reg (feature, "vr31", regnum++, 1, "lsx", 128, "lsxv"); ++ return regnum; ++} +diff --git a/gdb/features/loongarch/lsx.xml b/gdb/features/loongarch/lsx.xml +new file mode 100644 +index 0000000..e19a404 +--- /dev/null ++++ b/gdb/features/loongarch/lsx.xml +@@ -0,0 +1,59 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c +index 5eb32b0..297e5dc 100644 +--- a/gdb/loongarch-linux-nat.c ++++ b/gdb/loongarch-linux-nat.c +@@ -146,6 +146,125 @@ store_fpregs_to_thread (struct regcache *regcache, int regnum, pid_t tid) + } + } + ++/* Fill GDB's register array with the Loongson SIMD Extension ++ register values from the current thread. */ ++ ++static void ++fetch_lsxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid) ++{ ++ elf_lsxregset_t regset; ++ ++ if ((regnum == -1) ++ || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM)) ++ { ++ struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0) ++ { ++ /* If kernel dose not support lsx, just return. */ ++ if (errno == EINVAL) ++ return; ++ ++ perror_with_name (_("Couldn't get NT_LARCH_LSX registers")); ++ } ++ else ++ loongarch_lsxregset.supply_regset (nullptr, regcache, -1, ++ ®set, sizeof (regset)); ++ } ++} ++ ++/* Store to the current thread the valid Loongson SIMD Extension ++ register values in the GDB's register array. */ ++ ++static void ++store_lsxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid) ++{ ++ elf_lsxregset_t regset; ++ ++ if ((regnum == -1) ++ || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM)) ++ { ++ struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0) ++ { ++ /* If kernel dose not support lsx, just return. */ ++ if (errno == EINVAL) ++ return; ++ ++ perror_with_name (_("Couldn't get NT_LARCH_LSX registers")); ++ } ++ else ++ { ++ loongarch_lsxregset.collect_regset (nullptr, regcache, regnum, ++ ®set, sizeof (regset)); ++ if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0) ++ perror_with_name (_("Couldn't set NT_LARCH_LSX registers")); ++ } ++ } ++} ++ ++/* Fill GDB's register array with the Loongson Advanced SIMD Extension ++ register values from the current thread. */ ++ ++static void ++fetch_lasxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid) ++{ ++ elf_lasxregset_t regset; ++ ++ if ((regnum == -1) ++ || (regnum >= LOONGARCH_FIRST_LASX_REGNUM ++ && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET)) ++ { ++ struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0) ++ { ++ /* If kernel dose not support lasx, just return. */ ++ if (errno == EINVAL) ++ return; ++ ++ perror_with_name (_("Couldn't get NT_LARCH_LSX registers")); ++ } ++ else ++ loongarch_lasxregset.supply_regset (nullptr, regcache, -1, ++ ®set, sizeof (regset)); ++ } ++} ++ ++/* Store to the current thread the valid Loongson Advanced SIMD Extension ++ register values in the GDB's register array. */ ++ ++static void ++store_lasxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid) ++{ ++ elf_lasxregset_t regset; ++ ++ if ((regnum == -1) ++ || (regnum >= LOONGARCH_FIRST_LASX_REGNUM ++ && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET)) ++ { ++ struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0) ++ { ++ /* If kernel dose not support lasx, just return. */ ++ if (errno == EINVAL) ++ return; ++ ++ perror_with_name (_("Couldn't get NT_LARCH_LSX registers")); ++ } ++ else ++ { ++ loongarch_lasxregset.collect_regset (nullptr, regcache, regnum, ++ ®set, sizeof (regset)); ++ if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0) ++ perror_with_name (_("Couldn't set NT_LARCH_LASX registers")); ++ } ++ } ++} ++ ++ + /* Implement the "fetch_registers" target_ops method. */ + + void +@@ -156,6 +275,8 @@ loongarch_linux_nat_target::fetch_registers (struct regcache *regcache, + + fetch_gregs_from_thread(regcache, regnum, tid); + fetch_fpregs_from_thread(regcache, regnum, tid); ++ fetch_lsxregs_from_thread(regcache, regnum, tid); ++ fetch_lasxregs_from_thread(regcache, regnum, tid); + } + + /* Implement the "store_registers" target_ops method. */ +@@ -168,6 +289,8 @@ loongarch_linux_nat_target::store_registers (struct regcache *regcache, + + store_gregs_to_thread (regcache, regnum, tid); + store_fpregs_to_thread(regcache, regnum, tid); ++ store_lsxregs_to_thread(regcache, regnum, tid); ++ store_lasxregs_to_thread(regcache, regnum, tid); + } + + /* Return the address in the core dump or inferior of register REGNO. */ +diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c +index a09e3a9..24028ee 100644 +--- a/gdb/loongarch-linux-tdep.c ++++ b/gdb/loongarch-linux-tdep.c +@@ -215,6 +215,129 @@ const struct regset loongarch_fpregset = + loongarch_fill_fpregset, + }; + ++/* Unpack elf_lsxregset_t into GDB's register cache. */ ++ ++static void ++loongarch_supply_lsxregset (const struct regset *regset, ++ struct regcache *regcache, int regnum, ++ const void *lsxrs, size_t len) ++{ ++ int lsxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LSX_REGNUM); ++ const gdb_byte *buf = nullptr; ++ ++ if (regnum == -1) ++ { ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++) ++ { ++ buf = (const gdb_byte*) lsxrs + lsxrsize * i; ++ regcache->raw_supply (LOONGARCH_FIRST_LSX_REGNUM + i, (const void *) buf); ++ } ++ ++ } ++ else if (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM) ++ { ++ buf = (const gdb_byte*) lsxrs + lsxrsize * (regnum - LOONGARCH_FIRST_LSX_REGNUM); ++ regcache->raw_supply (regnum, (const void *) buf); ++ } ++} ++ ++/* Pack the GDB's register cache value into an elf_lsxregset_t. */ ++ ++static void ++loongarch_fill_lsxregset (const struct regset *regset, ++ const struct regcache *regcache, int regnum, ++ void *lsxrs, size_t len) ++{ ++ int lsxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LSX_REGNUM); ++ gdb_byte *buf = nullptr; ++ ++ if (regnum == -1) ++ { ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++) ++ { ++ buf = (gdb_byte *) lsxrs + lsxrsize * i; ++ regcache->raw_collect (LOONGARCH_FIRST_LSX_REGNUM + i, (void *) buf); ++ } ++ } ++ else if (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM) ++ { ++ buf = (gdb_byte *) lsxrs + lsxrsize * (regnum - LOONGARCH_FIRST_LSX_REGNUM); ++ regcache->raw_collect (regnum, (void *) buf); ++ } ++} ++ ++/* Define the Loongson SIMD Extension register regset. */ ++ ++const struct regset loongarch_lsxregset = ++{ ++ nullptr, ++ loongarch_supply_lsxregset, ++ loongarch_fill_lsxregset, ++}; ++ ++/* Unpack elf_lasxregset_t into GDB's register cache. */ ++ ++static void ++loongarch_supply_lasxregset (const struct regset *regset, ++ struct regcache *regcache, int regnum, ++ const void *lasxrs, size_t len) ++{ ++ int lasxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LASX_REGNUM); ++ const gdb_byte *buf = nullptr; ++ ++ if (regnum == -1) ++ { ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++) ++ { ++ buf = (const gdb_byte*) lasxrs + lasxrsize * i; ++ regcache->raw_supply (LOONGARCH_FIRST_LASX_REGNUM + i, (const void *) buf); ++ } ++ ++ } ++ else if (regnum >= LOONGARCH_FIRST_LASX_REGNUM ++ && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET) ++ { ++ buf = (const gdb_byte*) lasxrs + lasxrsize * (regnum - LOONGARCH_FIRST_LASX_REGNUM); ++ regcache->raw_supply (regnum, (const void *) buf); ++ } ++} ++ ++/* Pack the GDB's register cache value into an elf_lasxregset_t. */ ++ ++static void ++loongarch_fill_lasxregset (const struct regset *regset, ++ const struct regcache *regcache, int regnum, ++ void *lasxrs, size_t len) ++{ ++ int lasxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LASX_REGNUM); ++ gdb_byte *buf = nullptr; ++ ++ if (regnum == -1) ++ { ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++) ++ { ++ buf = (gdb_byte *) lasxrs + lasxrsize * i; ++ regcache->raw_collect (LOONGARCH_FIRST_LASX_REGNUM + i, (void *) buf); ++ } ++ } ++ else if (regnum >= LOONGARCH_FIRST_LASX_REGNUM ++ && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET) ++ ++ { ++ buf = (gdb_byte *) lasxrs + lasxrsize * (regnum - LOONGARCH_FIRST_LASX_REGNUM); ++ regcache->raw_collect (regnum, (void *) buf); ++ } ++} ++ ++/* Define the Loongson Advanced SIMD Extension register regset. */ ++ ++const struct regset loongarch_lasxregset = ++{ ++ nullptr, ++ loongarch_supply_lasxregset, ++ loongarch_fill_lasxregset, ++}; ++ + /* Implement the "init" method of struct tramp_frame. */ + + #define LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET 128 +@@ -269,10 +392,17 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch, + int fcsrsize = register_size (gdbarch, LOONGARCH_FCSR_REGNUM); + int fpsize = fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize; ++ int lsxrsize = register_size (gdbarch, LOONGARCH_FIRST_LSX_REGNUM); ++ int lasxrsize = register_size (gdbarch, LOONGARCH_FIRST_LASX_REGNUM); + + cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * gprsize, + LOONGARCH_LINUX_NUM_GREGSET * gprsize, &loongarch_gregset, nullptr, cb_data); + cb (".reg2", fpsize, fpsize, &loongarch_fpregset, nullptr, cb_data); ++ cb (".reg-loongarch-lsx", lsxrsize, lsxrsize, ++ &loongarch_lsxregset, nullptr, cb_data); ++ cb (".reg-loongarch-lasx", lasxrsize, lasxrsize, ++ &loongarch_lasxregset, nullptr, cb_data); ++ + } + + /* The following value is derived from __NR_rt_sigreturn in +diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c +index 80520c6..ec82aa0 100644 +--- a/gdb/loongarch-tdep.c ++++ b/gdb/loongarch-tdep.c +@@ -24,6 +24,7 @@ + #include "frame-unwind.h" + #include "gdbcore.h" + #include "loongarch-tdep.h" ++#include "reggroups.h" + #include "target.h" + #include "target-descriptions.h" + #include "trad-frame.h" +@@ -1433,6 +1434,51 @@ loongarch_find_default_target_description (const struct gdbarch_info info) + return loongarch_lookup_target_description (features); + } + ++static int ++loongarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, ++ const struct reggroup *group) ++{ ++ if (gdbarch_register_name (gdbarch, regnum) == NULL ++ || *gdbarch_register_name (gdbarch, regnum) == '\0') ++ return 0; ++ ++ int raw_p = regnum < gdbarch_num_regs (gdbarch); ++ ++ if (group == save_reggroup || group == restore_reggroup) ++ return raw_p; ++ ++ if (group == all_reggroup) ++ return 1; ++ ++ if (0 <= regnum && regnum <= LOONGARCH_BADV_REGNUM) ++ return group == general_reggroup; ++ ++ /* Only ORIG_A0, PC, BADV in general_reggroup */ ++ if (group == general_reggroup) ++ return 0; ++ ++ if (LOONGARCH_FIRST_FP_REGNUM <= regnum && regnum <= LOONGARCH_FCSR_REGNUM) ++ return group == float_reggroup; ++ ++ /* Only $fx / $fccx / $fcsr in float_reggroup */ ++ if (group == float_reggroup) ++ return 0; ++ ++ if (LOONGARCH_FIRST_LSX_REGNUM <= regnum ++ && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET) ++ return group == vector_reggroup; ++ ++ /* Only $vrx / $xrx in vector_reggroup */ ++ if (group == vector_reggroup) ++ return 0; ++ ++ int ret = tdesc_register_in_reggroup_p (gdbarch, regnum, group); ++ if (ret != -1) ++ return ret; ++ ++ return default_register_reggroup_p (gdbarch, regnum, group); ++} ++ + /* Initialize the current architecture based on INFO */ + + static struct gdbarch * +@@ -1484,6 +1530,34 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + if (!valid_p) + return nullptr; + ++ const struct tdesc_feature *feature_lsx ++ = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.lsx"); ++ if (feature_lsx == nullptr) ++ return nullptr; ++ ++ /* Validate the description provides the lsx registers and ++ allocate their numbers. */ ++ regnum = LOONGARCH_FIRST_LSX_REGNUM; ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++) ++ valid_p &= tdesc_numbered_register (feature_lsx, tdesc_data.get (), regnum++, ++ loongarch_v_normal_name[i] + 1); ++ if (!valid_p) ++ return nullptr; ++ ++ const struct tdesc_feature *feature_lasx ++ = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.lasx"); ++ if (feature_lasx == nullptr) ++ return nullptr; ++ ++ /* Validate the description provides the lasx registers and ++ allocate their numbers. */ ++ regnum = LOONGARCH_FIRST_LASX_REGNUM; ++ for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++) ++ valid_p &= tdesc_numbered_register (feature_lasx, tdesc_data.get (), regnum++, ++ loongarch_x_normal_name[i] + 1); ++ if (!valid_p) ++ return nullptr; ++ + /* LoongArch code is always little-endian. */ + info.byte_order_for_code = BFD_ENDIAN_LITTLE; + +@@ -1584,6 +1658,7 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + + /* Hook in OS ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); ++ set_gdbarch_register_reggroup_p (gdbarch, loongarch_register_reggroup_p); + + return gdbarch; + } +diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h +index dc80cef..b4d7499 100644 +--- a/gdb/loongarch-tdep.h ++++ b/gdb/loongarch-tdep.h +@@ -30,6 +30,8 @@ + /* Register set definitions. */ + extern const struct regset loongarch_gregset; + extern const struct regset loongarch_fpregset; ++extern const struct regset loongarch_lsxregset; ++extern const struct regset loongarch_lasxregset; + + /* Target-dependent structure in gdbarch. */ + struct loongarch_gdbarch_tdep : gdbarch_tdep_base +diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-low.cc +index ead2e76..1dd8a25 100644 +--- a/gdbserver/linux-loongarch-low.cc ++++ b/gdbserver/linux-loongarch-low.cc +@@ -174,12 +174,64 @@ loongarch_store_fpregset (struct regcache *regcache, const void *buf) + supply_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); + } + ++/* Collect lsx regs from REGCACHE into BUF. */ ++ ++static void ++loongarch_fill_lsxregset (struct regcache *regcache, void *buf) ++{ ++ elf_lsxregset_t *regset = (elf_lsxregset_t *) buf; ++ int i; ++ ++ for (i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++) ++ collect_register (regcache, LOONGARCH_FIRST_LSX_REGNUM + i, *regset + i); ++} ++ ++/* Supply lsx regs from BUF into REGCACHE. */ ++ ++static void ++loongarch_store_lsxregset (struct regcache *regcache, const void *buf) ++{ ++ const elf_lsxregset_t *regset = (const elf_lsxregset_t *) buf; ++ int i; ++ ++ for (i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++) ++ supply_register (regcache, LOONGARCH_FIRST_LSX_REGNUM + i, *regset + i); ++} ++ ++/* Collect lasx regs from REGCACHE into BUF. */ ++ ++static void ++loongarch_fill_lasxregset (struct regcache *regcache, void *buf) ++{ ++ elf_lasxregset_t *regset = (elf_lasxregset_t *) buf; ++ int i; ++ ++ for (i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++) ++ collect_register (regcache, LOONGARCH_FIRST_LASX_REGNUM + i, *regset + i); ++} ++ ++/* Supply lasx regs from BUF into REGCACHE. */ ++ ++static void ++loongarch_store_lasxregset (struct regcache *regcache, const void *buf) ++{ ++ const elf_lasxregset_t *regset = (const elf_lasxregset_t *) buf; ++ int i; ++ ++ for (i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++) ++ supply_register (regcache, LOONGARCH_FIRST_LASX_REGNUM + i, *regset + i); ++} ++ + /* LoongArch/Linux regsets. */ + static struct regset_info loongarch_regsets[] = { + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, sizeof (elf_gregset_t), + GENERAL_REGS, loongarch_fill_gregset, loongarch_store_gregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET, sizeof (elf_fpregset_t), + FP_REGS, loongarch_fill_fpregset, loongarch_store_fpregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_LARCH_LSX, sizeof (elf_lsxregset_t), ++ OPTIONAL_REGS, loongarch_fill_lsxregset, loongarch_store_lsxregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_LARCH_LASX, sizeof (elf_lasxregset_t), ++ OPTIONAL_REGS, loongarch_fill_lasxregset, loongarch_store_lasxregset }, + NULL_REGSET + }; + +-- +2.41.0 + diff --git a/gdb.spec b/gdb.spec index fad080c464b68e28d94513f6d9a5193724aa982c..8f0d535c1e6ca56a272060dc6fe989b184b7a4d2 100644 --- a/gdb.spec +++ b/gdb.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 2.test %global _python_bytecompile_extra 0 %global librpmso librpm.so.9 @@ -68,6 +68,8 @@ patch051: gdb-Fix-CVE-2023-39128.patch patch052: gdb-Fix-CVE-2023-39129.patch patch053: gdb-Fix-CVE-2023-39130.patch +Patch1000: 0001-test.patch + BuildRequires: rpm-libs autoconf BuildRequires: readline-devel >= 6.2-4 BuildRequires: gcc-c++ ncurses-devel texinfo gettext flex bison