From a7e8aa01fceed4213a2b9677a6ad4cf3d80d3a37 Mon Sep 17 00:00:00 2001 From: Qing Zhang Date: Fri, 23 Sep 2022 14:04:19 +0800 Subject: [PATCH 5/5] gdb-Add LoongArch clfs system Signed-off-by: Qing Zhang --- gdb/arch/loongarch-linux-nat.c | 15 ++++---- gdb/arch/loongarch.c | 18 ++++------ gdb/arch/loongarch.h | 4 +-- gdb/features/loongarch/base32.c | 3 +- gdb/features/loongarch/base32.xml | 3 +- gdb/features/loongarch/base64.c | 3 +- gdb/features/loongarch/base64.xml | 3 +- gdb/loongarch-linux-nat.c | 10 +++--- gdb/loongarch-linux-tdep.c | 58 ++++++++++++++++++------------- gdb/loongarch-linux-tdep.h | 4 +-- gdb/loongarch-tdep.c | 14 +++++--- gdb/loongarch-tdep.h | 3 +- 12 files changed, 76 insertions(+), 62 deletions(-) diff --git a/gdb/arch/loongarch-linux-nat.c b/gdb/arch/loongarch-linux-nat.c index 70bf742..baf59f8 100644 --- a/gdb/arch/loongarch-linux-nat.c +++ b/gdb/arch/loongarch-linux-nat.c @@ -43,23 +43,23 @@ loongarch_cpucfg_may_ptrace (uint64_t rj, int tid) struct target_desc * loongarch_linux_read_description_runtime (int tid) { - int rlen, fpu32, fpu64, lbt, lsx, lasx; + int rlen, flen, lbt, lsx, lasx; uint32_t cpucfg1 = loongarch_cpucfg_may_ptrace (1, tid); rlen = cpucfg1 & 0x2 /* LA64 */ ? 64 : 32; uint32_t cpucfg2 = loongarch_cpucfg_may_ptrace (2, tid); - fpu32 = 0, fpu64 = 0; + flen = 0; if (cpucfg2 & 0x4 /* FP_DP */) - fpu64 = 1; + flen = 64; else if (cpucfg2 & 0x2 /* FP_SP */) - fpu32 = 1; - if (fpu32 || fpu64) + flen = 32; + if (flen) { loongarch_elf_fpregset_t regset; struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) < 0) - fpu32 = 0, fpu64 = 0; + flen = 0; } lbt = 0; @@ -89,6 +89,5 @@ loongarch_linux_read_description_runtime (int tid) lasx = 1; } - return loongarch_create_target_description (rlen, fpu32, fpu64, lbt, lsx, - lasx); + return loongarch_create_target_description (rlen, flen, lbt, lsx, lasx); } diff --git a/gdb/arch/loongarch.c b/gdb/arch/loongarch.c index 34307f5..9eab0aa 100644 --- a/gdb/arch/loongarch.c +++ b/gdb/arch/loongarch.c @@ -31,7 +31,7 @@ unsigned int loongarch_debug = 0; #include <../features/loongarch/lasx.c> target_desc * -loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt, +loongarch_create_target_description (int rlen, int flen, int lbt, int lsx, int lasx) { gdb_assert (rlen == 32 || rlen == 64); @@ -50,10 +50,10 @@ loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt, else gdb_assert_not_reached ("rlen unknown"); - if (fpu32) - regnum = create_feature_loongarch_fpu32 (tdesc.get (), regnum); - else if (fpu64) + if (flen == 64) regnum = create_feature_loongarch_fpu64 (tdesc.get (), regnum); + else if (flen == 32) + regnum = create_feature_loongarch_fpu32 (tdesc.get (), regnum); if (lbt && rlen == 32) regnum = create_feature_loongarch_lbt32 (tdesc.get (), regnum); @@ -70,13 +70,7 @@ loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt, } target_desc * -loongarch_get_base_target_description (int rlen) +loongarch_get_base_target_description (int rlen, int flen) { - if (rlen == 64) - return loongarch_create_target_description (64, 0, 0, 0, 0, 0); - else if (rlen == 32) - return loongarch_create_target_description (32, 0, 0, 0, 0, 0); - else - gdb_assert_not_reached ("rlen unknown"); - return NULL; + return loongarch_create_target_description (rlen, flen, 0, 0, 0); } diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h index dfe011f..997afab 100644 --- a/gdb/arch/loongarch.h +++ b/gdb/arch/loongarch.h @@ -26,10 +26,10 @@ extern unsigned int loongarch_debug; struct target_desc; -extern struct target_desc *loongarch_get_base_target_description (int rlen); +extern struct target_desc *loongarch_get_base_target_description (int rlen, int flen); extern struct target_desc * -loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt, +loongarch_create_target_description (int rlen, int flen, int lbt, int lsx, int lasx); #endif diff --git a/gdb/features/loongarch/base32.c b/gdb/features/loongarch/base32.c index b6f2d06..3fb35ef 100644 --- a/gdb/features/loongarch/base32.c +++ b/gdb/features/loongarch/base32.c @@ -41,7 +41,8 @@ create_feature_loongarch_base32 (struct target_desc *result, long regnum) tdesc_create_reg (feature, "r29", regnum++, 1, "general", 32, "uint32"); tdesc_create_reg (feature, "r30", regnum++, 1, "general", 32, "uint32"); tdesc_create_reg (feature, "r31", regnum++, 1, "general", 32, "uint32"); + tdesc_create_reg (feature, "orig_a0", regnum++, 1, "general", 32, "uint32"); tdesc_create_reg (feature, "pc", regnum++, 1, "general", 32, "code_ptr"); - tdesc_create_reg (feature, "badvaddr", regnum++, 1, "general", 32, "code_ptr"); + tdesc_create_reg (feature, "badv", regnum++, 1, "general", 32, "code_ptr"); return regnum; } diff --git a/gdb/features/loongarch/base32.xml b/gdb/features/loongarch/base32.xml index 0afe81b..4c44dbe 100644 --- a/gdb/features/loongarch/base32.xml +++ b/gdb/features/loongarch/base32.xml @@ -40,6 +40,7 @@ + - + diff --git a/gdb/features/loongarch/base64.c b/gdb/features/loongarch/base64.c index 3ee2d9a..d84d425 100644 --- a/gdb/features/loongarch/base64.c +++ b/gdb/features/loongarch/base64.c @@ -41,7 +41,8 @@ create_feature_loongarch_base64 (struct target_desc *result, long regnum) tdesc_create_reg (feature, "r29", regnum++, 1, "general", 64, "uint64"); tdesc_create_reg (feature, "r30", regnum++, 1, "general", 64, "uint64"); tdesc_create_reg (feature, "r31", regnum++, 1, "general", 64, "uint64"); + tdesc_create_reg (feature, "orig_a0", regnum++, 1, "general", 64, "uint64"); tdesc_create_reg (feature, "pc", regnum++, 1, "general", 64, "code_ptr"); - tdesc_create_reg (feature, "badvaddr", regnum++, 1, "general", 64, "code_ptr"); + tdesc_create_reg (feature, "badv", regnum++, 1, "general", 64, "code_ptr"); return regnum; } diff --git a/gdb/features/loongarch/base64.xml b/gdb/features/loongarch/base64.xml index b53479f..05d766e 100644 --- a/gdb/features/loongarch/base64.xml +++ b/gdb/features/loongarch/base64.xml @@ -40,6 +40,7 @@ + - + diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c index f31eff4..e79b660 100644 --- a/gdb/loongarch-linux-nat.c +++ b/gdb/loongarch-linux-nat.c @@ -89,7 +89,7 @@ loongarch_linux_nat_target::read_description () return loongarch_linux_read_description_runtime (inferior_ptid.pid ()); } -/* Fill GDB's register array with the general-purpose, pc and badvaddr +/* Fill GDB's register array with the general-purpose, orig_a0, pc and badv register values from the current thread. */ static void @@ -99,7 +99,8 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid) loongarch_elf_gregset_t regset; if ((regno == -1) || (regs->r <= regno && regno < regs->r + 32) || - (regs->pc == regno) || (regs->badvaddr == regno)) + (regs->orig_a0 == regno) || (regs->pc == regno) || + (regs->badv == regno)) { struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; @@ -111,7 +112,7 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid) } } -/* Store to the current thread the valid general-purpose, pc and badvaddr +/* Store to the current thread the valid general-purpose, orig_a0, pc and badv register values in the GDB's register array. */ static void @@ -121,7 +122,8 @@ store_gregs_to_thread (struct regcache *regcache, int regno, pid_t tid) loongarch_elf_gregset_t regset; if ((regno == -1) || (regs->r <= regno && regno < regs->r + 32) || - (regs->pc == regno) || (regs->badvaddr == regno)) + (regs->orig_a0 == regno) || (regs->pc == regno) || + (regs->badv == regno)) { struct iovec iovec = { .iov_base = ®set, .iov_len = sizeof (regset) }; diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c index 1145d9e..7b4b9fa 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -63,19 +63,24 @@ loongarch_supply_elf_gregset (const struct regset *r, regcache->raw_supply (regs->r + i, (const void *)buf); } + /* Size base (orig_a0) = regsize * regs->orig_a0. */ + buf = (const gdb_byte*)gprs + regsize * regs->orig_a0; + regcache->raw_supply (regs->orig_a0, (const void *)buf); + /* Size base (pc) = regsize * regs->pc. */ buf = (const gdb_byte*)gprs + regsize * regs->pc; regcache->raw_supply (regs->pc, (const void *)buf); - /* Size base (badvaddr) = regsize * regs->badvaddr. */ - buf = (const gdb_byte*)gprs + regsize * regs->badvaddr; - regcache->raw_supply (regs->badvaddr, (const void *)buf); + /* Size base (badv) = regsize * regs->badv. */ + buf = (const gdb_byte*)gprs + regsize * regs->badv; + regcache->raw_supply (regs->badv, (const void *)buf); } else if (regs->r == regno) regcache->raw_supply_zeroed (regno); else if ((regs->r < regno && regno < regs->r + 32) + || (regs->orig_a0 == regno) || (regs->pc == regno) - || (regs->badvaddr == regno)) + || (regs->badv == regno)) { /* Offset offset (regno) = regsize * (regno - regs->r). */ buf = (const gdb_byte*)gprs + regsize * (regno - regs->r); @@ -101,17 +106,22 @@ loongarch_fill_elf_gregset (const struct regset *r, regcache->raw_collect (regs->r + i, (void *)buf); } + /* Size base (orig_a0) = regsize * regs->orig_a0. */ + buf = (gdb_byte *)gprs + regsize * regs->orig_a0; + regcache->raw_collect (regs->orig_a0, (void *)buf); + /* Size base (pc) = regsize * regs->pc. */ buf = (gdb_byte *)gprs + regsize * regs->pc; regcache->raw_collect (regs->pc, (void *)buf); - /* Size base (badvaddr) = regsize * regs->badvaddr. */ - buf = (gdb_byte *)gprs + regsize * regs->badvaddr; - regcache->raw_collect (regs->badvaddr, (void *)buf); + /* Size base (badv) = regsize * regs->badv. */ + buf = (gdb_byte *)gprs + regsize * regs->badv; + regcache->raw_collect (regs->badv, (void *)buf); } else if ((regs->r <= regno && regno < regs->r + 32) + ||(regs->orig_a0 == regno) ||(regs->pc == regno) - ||(regs->badvaddr == regno)) + ||(regs->badv == regno)) { /* Offset offset (regno) = regsize * (regno - regs->r). */ buf = (gdb_byte *)gprs + regsize * (regno - regs->r); @@ -541,42 +551,42 @@ static const struct target_desc * loongarch_linux_core_read_description (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd) { - int rlen, fpu32, fpu64, lbt, lsx, lasx; + int rlen, flen, fpu64, lbt, lsx, lasx; rlen = 64; - fpu32 = 0; fpu64 = !!bfd_get_section_by_name (abfd, ".reg2"); lbt = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lbt"); lsx = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lsx"); lasx = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lasx"); - return loongarch_create_target_description (rlen, fpu32, fpu64, lbt, lsx, - lasx); + if (fpu64) + flen = 64; + else + flen = 0; + + return loongarch_create_target_description (rlen, flen, lbt, lsx, lasx); } /* The RT signal frames look like this: struct rt_sigframe { - u32 rs_ass[4]; - u32 rs_pad[2]; struct siginfo rs_info; - struct ucontext rs_uc; + struct ucontext rs_uctx; }; struct ucontext { unsigned long uc_flags; struct ucontext *uc_link; stack_t uc_stack; - struct sigcontext uc_mcontext; sigset_t uc_sigmask; - unsigned long long uc_extcontext[0]; - }; */ - -#define RTSIGFRAME_SIGINFO_SIZE 136 -#define RTSIGFRAME_SIGINFO_OFFSET (6 * 4) -#define UCONTEXT_SIGCONTEXT_OFFSET 64 -#define RTSIGFRAME_SIGCONTEXT_OFFSET (RTSIGFRAME_SIGINFO_OFFSET \ - + RTSIGFRAME_SIGINFO_SIZE \ + _u8 __unused[1024 / 8 - sizeof(sigset_t)]; + struct sigcontext uc_mcontext; + }; +}; */ + +#define RTSIGFRAME_SIGINFO_SIZE 128 +#define UCONTEXT_SIGCONTEXT_OFFSET 176 +#define RTSIGFRAME_SIGCONTEXT_OFFSET (RTSIGFRAME_SIGINFO_SIZE \ + UCONTEXT_SIGCONTEXT_OFFSET) static void diff --git a/gdb/loongarch-linux-tdep.h b/gdb/loongarch-linux-tdep.h index e3456a8..bb70043 100644 --- a/gdb/loongarch-linux-tdep.h +++ b/gdb/loongarch-linux-tdep.h @@ -26,10 +26,10 @@ #define ELF_NGREG 45 #define ELF_NFPREG 34 -typedef uint64_t loongarch_elf_gregset_t[ELF_NGREG]; +typedef unsigned long loongarch_elf_gregset_t[ELF_NGREG]; extern const struct regset loongarch_elf_gregset; -typedef uint64_t loongarch_elf_fpregset_t[ELF_NFPREG]; +typedef double loongarch_elf_fpregset_t[ELF_NFPREG]; extern const struct regset loongarch_elf_fpregset; /* Regset variable size. */ diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 87331bd..d306bbc 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -1383,7 +1383,8 @@ loongarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, return 1; if (group == general_reggroup - && (regs->pc == regnum || regs->badvaddr == regnum + && (regs->orig_a0 == regnum || regs->pc == regnum + || regs->badv == regnum || (regs->r <= regnum && regnum < regs->r + 32))) return 1; @@ -1561,8 +1562,8 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) memset (tdep, 0, sizeof (*tdep)); memset (&tdep->regs, -1, sizeof (tdep->regs)); - /* If abfd is nullptr then a EF_LOONGARCH_ABI_LP64 is returned in - its default state. */ + /* If abfd is nullptr then a EF_LOONGARCH_ABI_LP64 | EF_LOONGARCH_FLOAT_ABI_DOUBLE + is returned in its default state. */ if (info.abfd != NULL && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) { @@ -1587,7 +1588,8 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Check any target description for validity. */ if (!tdesc_has_registers (tdesc)) tdesc = loongarch_get_base_target_description ( - EF_LOONGARCH_IS_ILP32 (tdep->ef_abi) ? 32 : 64); + EF_LOONGARCH_IS_ILP32 (tdep->ef_abi) ? 32 : 64, + EF_LOONGARCH_IS_SINGLE_FLOAT (tdep->ef_abi) ? 32 : 64); int valid_p = 1; const struct tdesc_feature *feature; @@ -1602,11 +1604,13 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) for (i = 0; i < 32; i++) valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), regnum++, loongarch_r_normal_name[i] + 1); + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), + tdep->regs.orig_a0 = regnum++, "orig_a0"); valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), tdep->regs.pc = regnum++, "pc"); valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), - tdep->regs.badvaddr = regnum++, "badvaddr"); + tdep->regs.badv = regnum++, "badv"); if ((feature = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.fpu"))) { diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h index c673c9e..12bc78e 100644 --- a/gdb/loongarch-tdep.h +++ b/gdb/loongarch-tdep.h @@ -37,8 +37,9 @@ struct gdbarch_tdep int r; int ra; int sp; + int orig_a0; int pc; - int badvaddr; + int badv; int f; int fcc; -- 2.36.0