aboutsummaryrefslogtreecommitdiff
path: root/gdb/loongarch-linux-nat.c
diff options
context:
space:
mode:
authorFeiyang Chen <chenfeiyang@loongson.cn>2024-01-25 16:32:36 +0800
committerTiezhu Yang <yangtiezhu@loongson.cn>2024-02-06 18:40:19 +0800
commite4d74c01e77365f1327e4e567e7579cdd3bf74f6 (patch)
tree57a80ffa2ea61b4754b9d71f89fcee012966bf05 /gdb/loongarch-linux-nat.c
parent1e9569f383a3d5a88ee07d0c2401bd95613c222e (diff)
downloadgdb-e4d74c01e77365f1327e4e567e7579cdd3bf74f6.zip
gdb-e4d74c01e77365f1327e4e567e7579cdd3bf74f6.tar.gz
gdb-e4d74c01e77365f1327e4e567e7579cdd3bf74f6.tar.bz2
gdb: LoongArch: Add LBT extension support
Loongson Binary Translation (LBT) is used to accelerate binary translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop). This patch support gdb to fetch/store these registers. Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn> # Framework Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> # Detail Optimizes Signed-off-by: Hui Li <lihui@loongson.cn> # Error Fixes Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Diffstat (limited to 'gdb/loongarch-linux-nat.c')
-rw-r--r--gdb/loongarch-linux-nat.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c
index 85d0a96..9bceb8a 100644
--- a/gdb/loongarch-linux-nat.c
+++ b/gdb/loongarch-linux-nat.c
@@ -265,6 +265,70 @@ store_lasxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
}
+/* Fill GDB's register array with the lbt register values
+ from the current thread. */
+
+static void
+fetch_lbt_from_thread (struct regcache *regcache, int regnum, pid_t tid)
+{
+ gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];
+
+ if (regnum == -1
+ || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
+ && regnum <= LOONGARCH_FTOP_REGNUM))
+ {
+ struct iovec iov;
+
+ iov.iov_base = regset;
+ iov.iov_len = LOONGARCH_LBT_REGS_SIZE;
+
+ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
+ {
+ /* If kernel dose not support lbt, just return. */
+ if (errno == EINVAL)
+ return;
+ perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
+ }
+ else
+ loongarch_lbtregset.supply_regset (nullptr, regcache, -1,
+ regset, LOONGARCH_LBT_REGS_SIZE);
+ }
+}
+
+/* Store to the current thread the valid lbt register values
+ in the GDB's register array. */
+
+static void
+store_lbt_to_thread (struct regcache *regcache, int regnum, pid_t tid)
+{
+ gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];
+
+ if (regnum == -1
+ || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
+ && regnum <= LOONGARCH_FTOP_REGNUM))
+ {
+ struct iovec iov;
+
+ iov.iov_base = regset;
+ iov.iov_len = LOONGARCH_LBT_REGS_SIZE;
+
+ if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
+ {
+ /* If kernel dose not support lbt, just return. */
+ if (errno == EINVAL)
+ return;
+ perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
+ }
+ else
+ {
+ loongarch_lbtregset.collect_regset (nullptr, regcache, regnum,
+ regset, LOONGARCH_LBT_REGS_SIZE);
+ if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
+ perror_with_name (_("Couldn't set NT_LARCH_LBT registers"));
+ }
+ }
+}
+
/* Implement the "fetch_registers" target_ops method. */
void
@@ -277,6 +341,7 @@ loongarch_linux_nat_target::fetch_registers (struct regcache *regcache,
fetch_fpregs_from_thread(regcache, regnum, tid);
fetch_lsxregs_from_thread(regcache, regnum, tid);
fetch_lasxregs_from_thread(regcache, regnum, tid);
+ fetch_lbt_from_thread (regcache, regnum, tid);
}
/* Implement the "store_registers" target_ops method. */
@@ -291,6 +356,7 @@ loongarch_linux_nat_target::store_registers (struct regcache *regcache,
store_fpregs_to_thread(regcache, regnum, tid);
store_lsxregs_to_thread(regcache, regnum, tid);
store_lasxregs_to_thread(regcache, regnum, tid);
+ store_lbt_to_thread (regcache, regnum, tid);
}
/* Return the address in the core dump or inferior of register REGNO. */