diff options
author | Feiyang Chen <chenfeiyang@loongson.cn> | 2024-01-25 16:32:36 +0800 |
---|---|---|
committer | Tiezhu Yang <yangtiezhu@loongson.cn> | 2024-02-06 18:40:19 +0800 |
commit | e4d74c01e77365f1327e4e567e7579cdd3bf74f6 (patch) | |
tree | 57a80ffa2ea61b4754b9d71f89fcee012966bf05 /gdb/loongarch-linux-nat.c | |
parent | 1e9569f383a3d5a88ee07d0c2401bd95613c222e (diff) | |
download | gdb-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.c | 66 |
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. */ |