gdb: LoongArch: Define register numbers and clean up code
authorTiezhu Yang <yangtiezhu@loongson.cn>
Sat, 25 Jun 2022 01:20:00 +0000 (09:20 +0800)
committerTiezhu Yang <yangtiezhu@loongson.cn>
Sat, 25 Jun 2022 02:12:48 +0000 (10:12 +0800)
This commit defines register numbers of various important registers,
we can use them directly in the related code, and also clean up some
code to make them more clear and readable.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
gdb/loongarch-linux-nat.c
gdb/loongarch-linux-tdep.c
gdb/loongarch-tdep.c
gdb/loongarch-tdep.h

index edc3d697d7bf063da7b40f45a655fc2e7801f3eb..c341e7199e39efae77e1a22bbceb4d6f67033069 100644 (file)
@@ -40,23 +40,21 @@ public:
 
 protected:
   /* Override linux_nat_trad_target methods.  */
-  CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regno,
-                               int store_p) override;
+  CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regnum,
+                              int store_p) override;
 };
 
 /* Fill GDB's register array with the general-purpose, pc and badv
    register values from the current thread.  */
 
 static void
-fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid)
+fetch_gregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
-  auto regs = tdep->regs;
   elf_gregset_t regset;
 
-  if (regno == -1 || (regs.r <= regno && regno < regs.r + 32)
-      || regs.pc == regno || regs.badv == regno)
+  if (regnum == -1 || (regnum >= 0 && regnum < 32)
+      || regnum == LOONGARCH_PC_REGNUM
+      || regnum == LOONGARCH_BADV_REGNUM)
   {
     struct iovec iov;
 
@@ -66,7 +64,7 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid)
     if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
       perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
     else
-      loongarch_gregset.supply_regset (nullptr, regcache, regno,
+      loongarch_gregset.supply_regset (nullptr, regcache, regnum,
                                       &regset, sizeof (regset));
   }
 }
@@ -75,15 +73,13 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid)
    register values in the GDB's register array.  */
 
 static void
-store_gregs_to_thread (struct regcache *regcache, int regno, pid_t tid)
+store_gregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
-  auto regs = tdep->regs;
   elf_gregset_t regset;
 
-  if (regno == -1 || (regs.r <= regno && regno < regs.r + 32)
-      || regs.pc == regno || regs.badv == regno)
+  if (regnum == -1 || (regnum >= 0 && regnum < 32)
+      || regnum == LOONGARCH_PC_REGNUM
+      || regnum == LOONGARCH_BADV_REGNUM)
   {
     struct iovec iov;
 
@@ -94,7 +90,7 @@ store_gregs_to_thread (struct regcache *regcache, int regno, pid_t tid)
       perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
     else
       {
-       loongarch_gregset.collect_regset (nullptr, regcache, regno,
+       loongarch_gregset.collect_regset (nullptr, regcache, regnum,
                                          &regset, sizeof (regset));
        if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
          perror_with_name (_("Couldn't set NT_PRSTATUS registers"));
@@ -106,39 +102,34 @@ store_gregs_to_thread (struct regcache *regcache, int regno, pid_t tid)
 
 void
 loongarch_linux_nat_target::fetch_registers (struct regcache *regcache,
-                                            int regno)
+                                            int regnum)
 {
   pid_t tid = get_ptrace_pid (regcache->ptid ());
 
-  fetch_gregs_from_thread(regcache, regno, tid);
+  fetch_gregs_from_thread(regcache, regnum, tid);
 }
 
 /* Implement the "store_registers" target_ops method.  */
 
 void
 loongarch_linux_nat_target::store_registers (struct regcache *regcache,
-                                            int regno)
+                                            int regnum)
 {
   pid_t tid = get_ptrace_pid (regcache->ptid ());
 
-  store_gregs_to_thread (regcache, regno, tid);
+  store_gregs_to_thread (regcache, regnum, tid);
 }
 
 /* Return the address in the core dump or inferior of register REGNO.  */
 
 CORE_ADDR
 loongarch_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
-                                              int regno, int store_p)
+                                              int regnum, int store_p)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
-
-  /* According to <asm/ptrace.h> */
-  if (0 <= regs.r && regs.r <= regno && regno < regs.r + GPR_NUM)
-    return GPR_BASE + regno - regs.r;
-  else if (regs.pc == regno)
-    return PC;
+  if (regnum >= 0 && regnum < 32)
+    return regnum;
+  else if (regnum == LOONGARCH_PC_REGNUM)
+    return LOONGARCH_PC_REGNUM;
   else
     return -1;
 }
@@ -156,9 +147,9 @@ supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregset)
 
 void
 fill_gregset (const struct regcache *regcache, gdb_gregset_t *gregset,
-             int regno)
+             int regnum)
 {
-  loongarch_gregset.collect_regset (nullptr, regcache, regno, gregset,
+  loongarch_gregset.collect_regset (nullptr, regcache, regnum, gregset,
                                    sizeof (gdb_gregset_t));
 }
 
@@ -169,7 +160,7 @@ supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregset)
 
 void
 fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset,
-              int regno)
+              int regnum)
 {
 }
 
index 372643761b128d9435aad15539f34cecc3659034..5da48a4e0a59f3628f77b31f13e0490934cf7a9e 100644 (file)
 #include "trad-frame.h"
 #include "tramp-frame.h"
 
-/* The general-purpose regset consists of 32 R registers, plus PC,
-   and BADV registers.  In addition, reserved 11 for extension in glibc.  */
-
-#define LOONGARCH_LINUX_NUM_GREGSET    (45)
-
 /* Unpack an elf_gregset_t into GDB's register cache.  */
 
 static void
-loongarch_supply_gregset (const struct regset *r,
-                         struct regcache *regcache, int regno,
+loongarch_supply_gregset (const struct regset *regset,
+                         struct regcache *regcache, int regnum,
                          const void *gprs, size_t len)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
-  auto regs = tdep->regs;
-
-  int regsize = register_size (regcache->arch (), regs.r);
+  int regsize = register_size (regcache->arch (), 0);
   const gdb_byte *buf = nullptr;
 
-  if (regno == -1)
+  if (regnum == -1)
     {
-      /* Set $r0 = 0.  */
-      regcache->raw_supply_zeroed (regs.r);
+      regcache->raw_supply_zeroed (0);
 
       for (int i = 1; i < 32; i++)
        {
          buf = (const gdb_byte*) gprs + regsize * i;
-         regcache->raw_supply (regs.r + i, (const void *) buf);
+         regcache->raw_supply (i, (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);
+      buf = (const gdb_byte*) gprs + regsize * LOONGARCH_PC_REGNUM;
+      regcache->raw_supply (LOONGARCH_PC_REGNUM, (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);
+      buf = (const gdb_byte*) gprs + regsize * LOONGARCH_BADV_REGNUM;
+      regcache->raw_supply (LOONGARCH_BADV_REGNUM, (const void *) buf);
     }
-  else if (regs.r == regno)
-    regcache->raw_supply_zeroed (regno);
-  else if ((regs.r < regno && regno < regs.r + 32)
-          || regs.pc == regno || regs.badv == regno)
+  else if (regnum == 0)
+    regcache->raw_supply_zeroed (0);
+  else if ((regnum > 0 && regnum < 32)
+          || regnum == LOONGARCH_PC_REGNUM
+          || regnum == LOONGARCH_BADV_REGNUM)
     {
-      /* Offset offset (regno) = regsize * (regno - regs.r).  */
-      buf = (const gdb_byte*) gprs + regsize * (regno - regs.r);
-      regcache->raw_supply (regno, (const void *) buf);
+      buf = (const gdb_byte*) gprs + regsize * regnum;
+      regcache->raw_supply (regnum, (const void *) buf);
     }
 }
 
 /* Pack the GDB's register cache value into an elf_gregset_t.  */
 
 static void
-loongarch_fill_gregset (const struct regset *r,
-                       const struct regcache *regcache, int regno,
+loongarch_fill_gregset (const struct regset *regset,
+                       const struct regcache *regcache, int regnum,
                        void *gprs, size_t len)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
-  auto regs = tdep->regs;
-  int regsize = register_size (regcache->arch (), regs.r);
+  int regsize = register_size (regcache->arch (), 0);
   gdb_byte *buf = nullptr;
 
-  if (regno == -1)
+  if (regnum == -1)
     {
       for (int i = 0; i < 32; i++)
        {
          buf = (gdb_byte *) gprs + regsize * i;
-         regcache->raw_collect (regs.r + i, (void *) buf);
+         regcache->raw_collect (i, (void *) buf);
        }
 
-      /* Size base (pc) = regsize * regs.pc.  */
-      buf = (gdb_byte *) gprs + regsize * regs.pc;
-      regcache->raw_collect (regs.pc, (void *) buf);
+      buf = (gdb_byte *) gprs + regsize * LOONGARCH_PC_REGNUM;
+      regcache->raw_collect (LOONGARCH_PC_REGNUM, (void *) buf);
 
-      /* Size base (badv) = regsize * regs.badv.  */
-      buf = (gdb_byte *) gprs + regsize * regs.badv;
-      regcache->raw_collect (regs.badv, (void *) buf);
+      buf = (gdb_byte *) gprs + regsize * LOONGARCH_BADV_REGNUM;
+      regcache->raw_collect (LOONGARCH_BADV_REGNUM, (void *) buf);
     }
-  else if ((regs.r <= regno && regno < regs.r + 32)
-          || regs.pc == regno || regs.badv == regno)
+  else if ((regnum >= 0 && regnum < 32)
+          || regnum == LOONGARCH_PC_REGNUM
+          || regnum == LOONGARCH_BADV_REGNUM)
     {
-      /* Offset offset (regno) = regsize * (regno - regs.r).  */
-      buf = (gdb_byte *) gprs + regsize * (regno - regs.r);
-      regcache->raw_collect (regno, (void *) buf);
+      buf = (gdb_byte *) gprs + regsize * regnum;
+      regcache->raw_collect (regnum, (void *) buf);
     }
 }
 
@@ -135,17 +118,13 @@ loongarch_linux_rt_sigframe_init (const struct tramp_frame *self,
                                  struct trad_frame_cache *this_cache,
                                  CORE_ADDR func)
 {
-  struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
-
   CORE_ADDR frame_sp = get_frame_sp (this_frame);
   CORE_ADDR sigcontext_base = (frame_sp + LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET
                               + LOONGARCH_UCONTEXT_SIGCONTEXT_OFFSET);
 
-  trad_frame_set_reg_addr (this_cache, regs.pc, sigcontext_base);
+  trad_frame_set_reg_addr (this_cache, LOONGARCH_PC_REGNUM, sigcontext_base);
   for (int i = 0; i < 32; i++)
-    trad_frame_set_reg_addr (this_cache, regs.r + i, sigcontext_base + 8 + i * 8);
+    trad_frame_set_reg_addr (this_cache, i, sigcontext_base + 8 + i * 8);
 
   trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
 }
@@ -176,10 +155,7 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
                                        void *cb_data,
                                        const struct regcache *regcache)
 {
-  loongarch_gdbarch_tdep *tdep
-    = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
-  int regsize = register_size (gdbarch, regs.r);
+  int regsize = register_size (gdbarch, 0);
 
   cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * regsize,
       LOONGARCH_LINUX_NUM_GREGSET * regsize, &loongarch_gregset, NULL, cb_data);
index e6b93a5cfcea6ee6eef7f7090040a37bbda4634b..3c02449a5e6dce6e5227249910d604660e01fab2 100644 (file)
@@ -116,10 +116,8 @@ loongarch_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
                         struct trad_frame_cache *this_cache)
 {
   CORE_ADDR cur_pc = start_pc, prologue_end = 0;
-  loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
-  int32_t sp = regs.r + 3;
-  int32_t fp = regs.r + 22;
+  int32_t sp = LOONGARCH_SP_REGNUM;
+  int32_t fp = LOONGARCH_FP_REGNUM;
   int32_t reg_value[32] = {0};
   int32_t reg_used[32] = {1, 0};
 
@@ -364,7 +362,7 @@ loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc
   return next_pcs;
 }
 
-/* Implement the "software_single_step" gdbarch method  */
+/* Implement the software_single_step gdbarch method  */
 
 static std::vector<CORE_ADDR>
 loongarch_software_single_step (struct regcache *regcache)
@@ -381,8 +379,7 @@ loongarch_software_single_step (struct regcache *regcache)
   return {next_pc};
 }
 
-/* Adjust the address downward (direction of stack growth) so that it
-   is correctly aligned for a new stack frame.  */
+/* Implement the frame_align gdbarch method.  */
 
 static CORE_ADDR
 loongarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
@@ -390,12 +387,11 @@ loongarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
   return align_down (addr, 16);
 }
 
-/* Generate, or return the cached frame cache for LoongArch frame unwinder.  */
+/* Generate, or return the cached frame cache for frame unwinder.  */
 
 static struct trad_frame_cache *
 loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct trad_frame_cache *cache;
   CORE_ADDR pc;
 
@@ -405,8 +401,7 @@ loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache = trad_frame_cache_zalloc (this_frame);
   *this_cache = cache;
 
-  loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  trad_frame_set_reg_realreg (cache, gdbarch_pc_regnum (gdbarch), tdep->regs.ra);
+  trad_frame_set_reg_realreg (cache, LOONGARCH_PC_REGNUM, LOONGARCH_RA_REGNUM);
 
   pc = get_frame_address_in_block (this_frame);
   trad_frame_set_id (cache, frame_id_build_unavailable_stack (pc));
@@ -414,7 +409,7 @@ loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
   return cache;
 }
 
-/* Implement the this_id callback for LoongArch frame unwinder.  */
+/* Implement the this_id callback for frame unwinder.  */
 
 static void
 loongarch_frame_this_id (struct frame_info *this_frame, void **prologue_cache,
@@ -426,7 +421,7 @@ loongarch_frame_this_id (struct frame_info *this_frame, void **prologue_cache,
   trad_frame_get_id (info, this_id);
 }
 
-/* Implement the prev_register callback for LoongArch frame unwinder.  */
+/* Implement the prev_register callback for frame unwinder.  */
 
 static struct value *
 loongarch_frame_prev_register (struct frame_info *this_frame,
@@ -450,15 +445,13 @@ static const struct frame_unwind loongarch_frame_unwind = {
   /*.prev_arch    =*/nullptr,
 };
 
-/* Implement the return_value gdbarch method for LoongArch.  */
+/* Implement the return_value gdbarch method.  */
 
 static enum return_value_convention
 loongarch_return_value (struct gdbarch *gdbarch, struct value *function,
                        struct type *type, struct regcache *regcache,
                        gdb_byte *readbuf, const gdb_byte *writebuf)
 {
-  loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
   int len = TYPE_LENGTH (type);
   int regnum = -1;
 
@@ -467,7 +460,7 @@ loongarch_return_value (struct gdbarch *gdbarch, struct value *function,
   switch (type->code ())
     {
       case TYPE_CODE_INT:
-       regnum = regs.r + 4;
+       regnum = LOONGARCH_A0_REGNUM;
        break;
     }
 
@@ -480,16 +473,13 @@ loongarch_return_value (struct gdbarch *gdbarch, struct value *function,
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-/* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */
+/* Implement the dwarf2_reg_to_regnum gdbarch method.  */
 
 static int
-loongarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
+loongarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
 {
-  loongarch_gdbarch_tdep *tdep = (loongarch_gdbarch_tdep *) gdbarch_tdep (gdbarch);
-  auto regs = tdep->regs;
-
-  if (0 <= num && num < 32)
-    return regs.r + num;
+  if (regnum >= 0 && regnum < 32)
+    return regnum;
   else
     return -1;
 }
@@ -572,7 +562,6 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   size_t regnum = 0;
   tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
   loongarch_gdbarch_tdep *tdep = new loongarch_gdbarch_tdep;
-  tdep->regs.r = regnum;
 
   /* Validate the description provides the mandatory base registers
      and allocate their numbers.  */
@@ -580,10 +569,8 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   for (int i = 0; i < 32; i++)
     valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++,
                                        loongarch_r_normal_name[i] + 1);
-  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (),
-                                     tdep->regs.pc = regnum++, "pc");
-  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (),
-                                     tdep->regs.badv = regnum++, "badv");
+  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++, "pc");
+  valid_p &= tdesc_numbered_register (feature_cpu, tdesc_data.get (), regnum++, "badv");
   if (!valid_p)
     return nullptr;
 
@@ -642,11 +629,9 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   info.tdesc_data = tdesc_data.get ();
 
   /* Information about registers.  */
-  tdep->regs.ra = tdep->regs.r + 1;
-  tdep->regs.sp = tdep->regs.r + 3;
   set_gdbarch_num_regs (gdbarch, regnum);
-  set_gdbarch_sp_regnum (gdbarch, tdep->regs.sp);
-  set_gdbarch_pc_regnum (gdbarch, tdep->regs.pc);
+  set_gdbarch_sp_regnum (gdbarch, LOONGARCH_SP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, LOONGARCH_PC_REGNUM);
 
   /* Finalise the target description registers.  */
   tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
index b2fd16e25a7c23cd8876592fa47c9a751d4d4a9d..f3efa4601eff54844e5e3d046cd0cefc02fc2a97 100644 (file)
 #include "elf/loongarch.h"
 #include "opcode/loongarch.h"
 
+/* Register numbers of various important registers.  */
+enum
+{
+  LOONGARCH_RA_REGNUM = 1,             /* Return Address.  */
+  LOONGARCH_SP_REGNUM = 3,             /* Stack Pointer.  */
+  LOONGARCH_A0_REGNUM = 4,             /* First Argument/Return Value.  */
+  LOONGARCH_A7_REGNUM = 11,            /* Seventh Argument/Syscall Number.  */
+  LOONGARCH_FP_REGNUM = 22,            /* Frame Pointer.  */
+  LOONGARCH_PC_REGNUM = 32,            /* Program Counter.  */
+  LOONGARCH_BADV_REGNUM = 33,          /* Bad Vaddr for Addressing Exception.  */
+  LOONGARCH_LINUX_NUM_GREGSET = 45,    /* 32 GPR, PC, BADV, RESERVED 11.  */
+};
+
 /* Register set definitions.  */
 extern const struct regset loongarch_gregset;
 
@@ -35,15 +48,6 @@ struct loongarch_gdbarch_tdep : gdbarch_tdep
 {
   /* Features about the abi that impact how the gdbarch is configured.  */
   struct loongarch_gdbarch_features abi_features;
-
-  struct
-  {
-    int r;     /* General register. */
-    int ra;    /* Return Address.  */
-    int sp;    /* Stack Pointer.  */
-    int pc;    /* Program Counter.  */
-    int badv;  /* Bad vaddr for addressing exception.  */
-  } regs;      /* LoongArch registers  */
 };
 
 #endif /* LOONGARCH_TDEP_H  */