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;
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));
}
}
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;
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"));
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;
}
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));
}
void
fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset,
- int regno)
+ int regnum)
{
}
#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);
}
}
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));
}
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);
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};
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)
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)
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;
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));
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,
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,
/*.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;
switch (type->code ())
{
case TYPE_CODE_INT:
- regnum = regs.r + 4;
+ regnum = LOONGARCH_A0_REGNUM;
break;
}
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;
}
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. */
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;
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));
#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;
{
/* 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 */