Skip to content

Commit

Permalink
gdb: LoongArch: add orig_a0 into register set
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Tiezhu Yang <[email protected]>
  • Loading branch information
xry111 authored and Tiezhu Yang committed Jul 5, 2022
1 parent 4694a0e commit 7369182
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 3 deletions.
1 change: 1 addition & 0 deletions gdb/features/loongarch/base32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions gdb/features/loongarch/base32.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
1 change: 1 addition & 0 deletions gdb/features/loongarch/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions gdb/features/loongarch/base64.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
2 changes: 2 additions & 0 deletions gdb/loongarch-linux-nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down
8 changes: 8 additions & 0 deletions gdb/loongarch-linux-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
{
Expand All @@ -83,13 +87,17 @@ 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);

buf = (gdb_byte *) gprs + regsize * LOONGARCH_BADV_REGNUM;
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)
{
Expand Down
1 change: 1 addition & 0 deletions gdb/loongarch-tdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions gdb/loongarch-tdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down

0 comments on commit 7369182

Please sign in to comment.