From 0757a50396e3638434f806aec2ee8c8f79a7026c Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Sat, 25 Jun 2022 09:20:00 +0800 Subject: [PATCH] gdb: LoongArch: Define register numbers and clean up code 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 --- gdb/loongarch-linux-nat.c | 57 ++++++++++------------- gdb/loongarch-linux-tdep.c | 92 ++++++++++++++------------------------ gdb/loongarch-tdep.c | 51 ++++++++------------- gdb/loongarch-tdep.h | 22 +++++---- 4 files changed, 89 insertions(+), 133 deletions(-) diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c index edc3d697d7b..c341e7199e3 100644 --- a/gdb/loongarch-linux-nat.c +++ b/gdb/loongarch-linux-nat.c @@ -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, ®set, 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, ®set, 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 */ - 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) { } diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c index 372643761b1..5da48a4e0a5 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -28,90 +28,73 @@ #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); diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index e6b93a5cfce..3c02449a5e6 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -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 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)); diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h index b2fd16e25a7..f3efa4601ef 100644 --- a/gdb/loongarch-tdep.h +++ b/gdb/loongarch-tdep.h @@ -27,6 +27,19 @@ #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 */ -- 2.30.2