gdb: LoongArch: add orig_a0 into register set
authorXi Ruoyao <xry111@xry111.site>
Tue, 5 Jul 2022 11:30:12 +0000 (19:30 +0800)
committerTiezhu Yang <yangtiezhu@loongson.cn>
Tue, 5 Jul 2022 14:26:45 +0000 (22:26 +0800)
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>
gdb/features/loongarch/base32.c
gdb/features/loongarch/base32.xml
gdb/features/loongarch/base64.c
gdb/features/loongarch/base64.xml
gdb/loongarch-linux-nat.c
gdb/loongarch-linux-tdep.c
gdb/loongarch-tdep.c
gdb/loongarch-tdep.h

index 7105c152aed3dea9cf01d36bd854ec7663105ba7..3fb35ef2d05a7f68b5e845e0e24e8534dd0db42f 100644 (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;
index 5b00f8a8d377760c3ecc73806af1b9a716973765..af47bbd3da4b30863515d68ac6cb92ca7df64d4b 100644 (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>
index 63eee02455458180072b3d244183e5ba741bc933..d84d42562947bdd267236231f2848a0920f2c213 100644 (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;
index bef91e50dd7ad9e61f5fc5d75f3ee2248b9d6d63..2d8a1f6b7349c3f19af9450b0100e9f3edc663d1 100644 (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>
index c341e7199e39efae77e1a22bbceb4d6f67033069..1fd1af6c99fc248395974affd09a0af4f4ce0924 100644 (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)
   {
index 21fc67f932315fbba685a3b28aa8977d11c2fc2f..1076e9359972b1fcbc6da192adafe8440ec204ad 100644 (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)
     {
index f2f4e3be909a56a4f4879f9ecaf66fe7e74b1e17..76480ce6c94470019dca95e5d4107676db18b160 100644 (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)
index 54b34af1d66620373b9031bcbe262ef0903ca4a9..acf0191fd651e6f99ab76273498e5a669e14234f 100644 (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.  */