gdb: LoongArch: add orig_a0 into register set

The basic support for LoongArch has been merged into the upstream Linux
kernel since 5.19-rc1 on June 5, 2022.  This commit adds orig_a0 which
is added into struct user_pt_regs [1] to match the upstream kernel, and
then the upstream GDB will work with the upstream kernel.

Note that orig_a0 was added into struct user_pt_regs in the development
cycle for merging LoongArch port into the upstream Linux kernel, so
earlier kernels (notably, the product kernel with version 4.19 used in
distros like UOS and Loongnix) don't have it.  Inspect
arch/loongarch/include/uapi/asm/ptrace.h in the kernel tree to make sure.
To build upstream GDB for a kernel lacking orig_a0, it's necessary to
revert this commit locally.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/uapi/asm/ptrace.h#n24

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
This commit is contained in:
Xi Ruoyao
2022-07-05 19:30:12 +08:00
committed by Tiezhu Yang
parent 4694a0e5fe
commit 736918239b
8 changed files with 19 additions and 3 deletions

View File

@ -41,6 +41,7 @@ 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, "badv", regnum++, 1, "general", 32, "code_ptr");
return regnum;

View File

@ -39,6 +39,7 @@
<reg name="r29" bitsize="32" type="uint32" group="general"/>
<reg name="r30" bitsize="32" type="uint32" group="general"/>
<reg name="r31" bitsize="32" type="uint32" group="general"/>
<reg name="orig_a0" bitsize="32" type="uint32" group="general"/>
<reg name="pc" bitsize="32" type="code_ptr" group="general"/>
<reg name="badv" bitsize="32" type="code_ptr" group="general"/>
</feature>

View File

@ -41,6 +41,7 @@ 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, "badv", regnum++, 1, "general", 64, "code_ptr");
return regnum;

View File

@ -39,6 +39,7 @@
<reg name="r29" bitsize="64" type="uint64" group="general"/>
<reg name="r30" bitsize="64" type="uint64" group="general"/>
<reg name="r31" bitsize="64" type="uint64" group="general"/>
<reg name="orig_a0" bitsize="64" type="uint64" group="general"/>
<reg name="pc" bitsize="64" type="code_ptr" group="general"/>
<reg name="badv" bitsize="64" type="code_ptr" group="general"/>
</feature>

View File

@ -53,6 +53,7 @@ fetch_gregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
elf_gregset_t regset;
if (regnum == -1 || (regnum >= 0 && regnum < 32)
|| regnum == LOONGARCH_ORIG_A0_REGNUM
|| regnum == LOONGARCH_PC_REGNUM
|| regnum == LOONGARCH_BADV_REGNUM)
{
@ -78,6 +79,7 @@ store_gregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
elf_gregset_t regset;
if (regnum == -1 || (regnum >= 0 && regnum < 32)
|| regnum == LOONGARCH_ORIG_A0_REGNUM
|| regnum == LOONGARCH_PC_REGNUM
|| regnum == LOONGARCH_BADV_REGNUM)
{

View File

@ -48,6 +48,9 @@ loongarch_supply_gregset (const struct regset *regset,
regcache->raw_supply (i, (const void *) buf);
}
buf = (const gdb_byte*) gprs + regsize * LOONGARCH_ORIG_A0_REGNUM;
regcache->raw_supply (LOONGARCH_ORIG_A0_REGNUM, (const void *) buf);
buf = (const gdb_byte*) gprs + regsize * LOONGARCH_PC_REGNUM;
regcache->raw_supply (LOONGARCH_PC_REGNUM, (const void *) buf);
@ -57,6 +60,7 @@ loongarch_supply_gregset (const struct regset *regset,
else if (regnum == 0)
regcache->raw_supply_zeroed (0);
else if ((regnum > 0 && regnum < 32)
|| regnum == LOONGARCH_ORIG_A0_REGNUM
|| regnum == LOONGARCH_PC_REGNUM
|| regnum == LOONGARCH_BADV_REGNUM)
{
@ -83,6 +87,9 @@ loongarch_fill_gregset (const struct regset *regset,
regcache->raw_collect (i, (void *) buf);
}
buf = (gdb_byte *) gprs + regsize * LOONGARCH_ORIG_A0_REGNUM;
regcache->raw_collect (LOONGARCH_ORIG_A0_REGNUM, (void *) buf);
buf = (gdb_byte *) gprs + regsize * LOONGARCH_PC_REGNUM;
regcache->raw_collect (LOONGARCH_PC_REGNUM, (void *) buf);
@ -90,6 +97,7 @@ loongarch_fill_gregset (const struct regset *regset,
regcache->raw_collect (LOONGARCH_BADV_REGNUM, (void *) buf);
}
else if ((regnum >= 0 && regnum < 32)
|| regnum == LOONGARCH_ORIG_A0_REGNUM
|| regnum == LOONGARCH_PC_REGNUM
|| regnum == LOONGARCH_BADV_REGNUM)
{

View File

@ -576,6 +576,7 @@ 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 (), regnum++, "orig_a0");
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)

View File

@ -35,9 +35,10 @@ enum
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. */
LOONGARCH_ORIG_A0_REGNUM = 32, /* Syscall's original arg0. */
LOONGARCH_PC_REGNUM = 33, /* Program Counter. */
LOONGARCH_BADV_REGNUM = 34, /* Bad Vaddr for Addressing Exception. */
LOONGARCH_LINUX_NUM_GREGSET = 45, /* 32 GPR, ORIG_A0, PC, BADV, RESERVED 10. */
};
/* Register set definitions. */