[v2] Fix GDB: Initial r16-r31 support for Intel APX

Message ID 20240320104703.117257-1-hjl.tools@gmail.com
State New
Headers
Series [v2] Fix GDB: Initial r16-r31 support for Intel APX |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gdb_build--master-arm fail Patch failed to apply

Commit Message

H.J. Lu March 20, 2024, 10:47 a.m. UTC
  ---
 gdb/amd64-tdep.c | 58 ++++++++++++++++++++++++++++++------------------
 gdb/i386-tdep.h  |  6 ++++-
 2 files changed, 41 insertions(+), 23 deletions(-)
  

Comments

H.J. Lu March 20, 2024, 11:12 a.m. UTC | #1
On Wed, Mar 20, 2024 at 3:47 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> ---
>  gdb/amd64-tdep.c | 58 ++++++++++++++++++++++++++++++------------------
>  gdb/i386-tdep.h  |  6 ++++-
>  2 files changed, 41 insertions(+), 23 deletions(-)
>
> diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
> index 9b641ea3ab6..786c9dd1db4 100644
> --- a/gdb/amd64-tdep.c
> +++ b/gdb/amd64-tdep.c
> @@ -467,15 +467,27 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
>      return i386_pseudo_register_name (gdbarch, regnum);
>  }
>
> -/* Convert the raw APX register number to the register number relative
> -   to r16.  NUM_BASE_REGS is the number of registers without APX.  */
> +/* Convert the APX byte and word register number to the register number
> +   relative to r16.  */
>
>  static int
> -amd64_apx_raw_register (i386_gdbarch_tdep *tdep, int gpnum,
> -                       int num_base_regs)
> +amd64_apx_byte_word_register (i386_gdbarch_tdep *tdep, int gpnum)
>  {
> -  if (gpnum >= num_base_regs)
> -    gpnum += tdep->r16_regnum - num_base_regs;
> +  if (gpnum >= 16)
> +    gpnum += tdep->r16_regnum - 16;
> +  return gpnum;
> +}
> +
> +/* Convert the APX dword register number to the register number relative
> +   to r16.  For x32, the last dword register is EIP.  */
> +
> +static int
> +amd64_apx_dword_register (i386_gdbarch_tdep *tdep, int gpnum)
> +{
> +  if (tdep->eip_regnum == gpnum)
> +    return AMD64_RIP_REGNUM;
> +  if (gpnum >= 16)
> +    gpnum += tdep->r16_regnum - 16;
>    return gpnum;
>  }
>
> @@ -499,21 +511,20 @@ amd64_pseudo_register_read_value (gdbarch *gdbarch, const frame_info_ptr &next_f
>         }
>        else
>         {
> -         gpnum = amd64_apx_raw_register (tdep, gpnum,
> -                                         tdep->num_byte_regs);
> +         gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>           return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
>         }
>      }
>    else if (i386_word_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->ax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
> +      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>        return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
>      }
>    else if (i386_dword_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->eax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
> +      gpnum = amd64_apx_dword_register (tdep, gpnum);
>        return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
>      }
>    else
> @@ -537,21 +548,20 @@ amd64_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
>         }
>        else
>         {
> -         gpnum = amd64_apx_raw_register (tdep, gpnum,
> -                                         tdep->num_byte_regs);
> +         gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>           pseudo_to_raw_part (next_frame, buf, gpnum, 0);
>         }
>      }
>    else if (i386_word_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->ax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
> +      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>        pseudo_to_raw_part (next_frame, buf, gpnum, 0);
>      }
>    else if (i386_dword_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->eax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
> +      gpnum = amd64_apx_dword_register (tdep, gpnum);
>        pseudo_to_raw_part (next_frame, buf, gpnum, 0);
>      }
>    else
> @@ -574,8 +584,7 @@ amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch,
>         ax_reg_mask (ax, gpnum - tdep->num_lower_byte_regs);
>        else
>         {
> -         gpnum = amd64_apx_raw_register (tdep, gpnum,
> -                                         tdep->num_byte_regs);
> +         gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>           ax_reg_mask (ax, gpnum);
>         }
>        return 0;
> @@ -583,14 +592,14 @@ amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch,
>    else if (i386_word_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->ax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
> +      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
>        ax_reg_mask (ax, gpnum);
>        return 0;
>      }
>    else if (i386_dword_regnum_p (gdbarch, regnum))
>      {
>        int gpnum = regnum - tdep->eax_regnum;
> -      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
> +      gpnum = amd64_apx_dword_register (tdep, gpnum);
>        ax_reg_mask (ax, gpnum);
>        return 0;
>      }
> @@ -3498,14 +3507,17 @@ static struct type *
>  amd64_x32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
>  {
>    i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
> +  int gpnum = regnum - tdep->eax_regnum;
> +
> +  /* %eip */
> +  if (gpnum == tdep->eip_regnum)
> +    return builtin_type (gdbarch)->builtin_func_ptr;
>
> -  switch (regnum - tdep->eax_regnum)
> +  switch (gpnum)
>      {
>      case AMD64_RBP_REGNUM:     /* %ebp */
>      case AMD64_RSP_REGNUM:     /* %esp */
>        return builtin_type (gdbarch)->builtin_data_ptr;
> -    case AMD64_RIP_REGNUM:     /* %eip */
> -      return builtin_type (gdbarch)->builtin_func_ptr;
>      }
>
>    return i386_pseudo_register_type (gdbarch, regnum);
> @@ -3519,7 +3531,9 @@ amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
>
>    amd64_init_abi (info, gdbarch, default_tdesc);
>
> -  /* Increment 1 for EIP.  */
> +  /* Set %eip to the last dword register.  */
> +  tdep->eip_regnum = tdep->num_dword_regs;
> +  /* Increment 1 for %eip.  */
>    tdep->num_dword_regs += 1;
>    set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_type);
>
> diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
> index b750800c7c4..08906e7ad53 100644
> --- a/gdb/i386-tdep.h
> +++ b/gdb/i386-tdep.h
> @@ -104,7 +104,7 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base
>    /* Number of byte registers.  */
>    int num_byte_regs = 0;
>
> -/* Number of lower byte registers.  Only used for AMD64.  */
> +  /* Number of pseudo lower byte registers.  Only used for AMD64.  */
>    int num_lower_byte_regs = 0;
>
>    /* Register pseudo number for %al.  */
> @@ -123,6 +123,10 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base
>       of pseudo dword register support.  */
>    int eax_regnum = 0;
>
> +  /* Register number for %eip.  Set this to -1 to indicate the absence
> +     of %eip support.  Only used for AMD64.  */
> +  int eip_regnum = -1;
> +
>    /* Number of core registers.  */
>    int num_core_regs = 0;
>
> --
> 2.44.0
>

Ignore this.  The wrong patch.
  

Patch

diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 9b641ea3ab6..786c9dd1db4 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -467,15 +467,27 @@  amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
     return i386_pseudo_register_name (gdbarch, regnum);
 }
 
-/* Convert the raw APX register number to the register number relative
-   to r16.  NUM_BASE_REGS is the number of registers without APX.  */
+/* Convert the APX byte and word register number to the register number
+   relative to r16.  */
 
 static int
-amd64_apx_raw_register (i386_gdbarch_tdep *tdep, int gpnum,
-			int num_base_regs)
+amd64_apx_byte_word_register (i386_gdbarch_tdep *tdep, int gpnum)
 {
-  if (gpnum >= num_base_regs)
-    gpnum += tdep->r16_regnum - num_base_regs;
+  if (gpnum >= 16)
+    gpnum += tdep->r16_regnum - 16;
+  return gpnum;
+}
+
+/* Convert the APX dword register number to the register number relative
+   to r16.  For x32, the last dword register is EIP.  */
+
+static int
+amd64_apx_dword_register (i386_gdbarch_tdep *tdep, int gpnum)
+{
+  if (tdep->eip_regnum == gpnum)
+    return AMD64_RIP_REGNUM;
+  if (gpnum >= 16)
+    gpnum += tdep->r16_regnum - 16;
   return gpnum;
 }
 
@@ -499,21 +511,20 @@  amd64_pseudo_register_read_value (gdbarch *gdbarch, const frame_info_ptr &next_f
 	}
       else
 	{
-	  gpnum = amd64_apx_raw_register (tdep, gpnum,
-					  tdep->num_byte_regs);
+	  gpnum = amd64_apx_byte_word_register (tdep, gpnum);
 	  return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
 	}
     }
   else if (i386_word_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->ax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
+      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
       return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
+      gpnum = amd64_apx_dword_register (tdep, gpnum);
       return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
     }
   else
@@ -537,21 +548,20 @@  amd64_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
 	}
       else
 	{
-	  gpnum = amd64_apx_raw_register (tdep, gpnum,
-					  tdep->num_byte_regs);
+	  gpnum = amd64_apx_byte_word_register (tdep, gpnum);
 	  pseudo_to_raw_part (next_frame, buf, gpnum, 0);
 	}
     }
   else if (i386_word_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->ax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
+      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
       pseudo_to_raw_part (next_frame, buf, gpnum, 0);
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
+      gpnum = amd64_apx_dword_register (tdep, gpnum);
       pseudo_to_raw_part (next_frame, buf, gpnum, 0);
     }
   else
@@ -574,8 +584,7 @@  amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch,
 	ax_reg_mask (ax, gpnum - tdep->num_lower_byte_regs);
       else
 	{
-	  gpnum = amd64_apx_raw_register (tdep, gpnum,
-					  tdep->num_byte_regs);
+	  gpnum = amd64_apx_byte_word_register (tdep, gpnum);
 	  ax_reg_mask (ax, gpnum);
 	}
       return 0;
@@ -583,14 +592,14 @@  amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch,
   else if (i386_word_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->ax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_word_regs);
+      gpnum = amd64_apx_byte_word_register (tdep, gpnum);
       ax_reg_mask (ax, gpnum);
       return 0;
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
-      gpnum = amd64_apx_raw_register (tdep, gpnum, tdep->num_dword_regs);
+      gpnum = amd64_apx_dword_register (tdep, gpnum);
       ax_reg_mask (ax, gpnum);
       return 0;
     }
@@ -3498,14 +3507,17 @@  static struct type *
 amd64_x32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+  int gpnum = regnum - tdep->eax_regnum;
+
+  /* %eip */
+  if (gpnum == tdep->eip_regnum)
+    return builtin_type (gdbarch)->builtin_func_ptr;
 
-  switch (regnum - tdep->eax_regnum)
+  switch (gpnum)
     {
     case AMD64_RBP_REGNUM:	/* %ebp */
     case AMD64_RSP_REGNUM:	/* %esp */
       return builtin_type (gdbarch)->builtin_data_ptr;
-    case AMD64_RIP_REGNUM:	/* %eip */
-      return builtin_type (gdbarch)->builtin_func_ptr;
     }
 
   return i386_pseudo_register_type (gdbarch, regnum);
@@ -3519,7 +3531,9 @@  amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
 
   amd64_init_abi (info, gdbarch, default_tdesc);
 
-  /* Increment 1 for EIP.  */
+  /* Set %eip to the last dword register.  */
+  tdep->eip_regnum = tdep->num_dword_regs;
+  /* Increment 1 for %eip.  */
   tdep->num_dword_regs += 1;
   set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_type);
 
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index b750800c7c4..08906e7ad53 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -104,7 +104,7 @@  struct i386_gdbarch_tdep : gdbarch_tdep_base
   /* Number of byte registers.  */
   int num_byte_regs = 0;
 
-/* Number of lower byte registers.  Only used for AMD64.  */
+  /* Number of pseudo lower byte registers.  Only used for AMD64.  */
   int num_lower_byte_regs = 0;
 
   /* Register pseudo number for %al.  */
@@ -123,6 +123,10 @@  struct i386_gdbarch_tdep : gdbarch_tdep_base
      of pseudo dword register support.  */
   int eax_regnum = 0;
 
+  /* Register number for %eip.  Set this to -1 to indicate the absence
+     of %eip support.  Only used for AMD64.  */
+  int eip_regnum = -1;
+
   /* Number of core registers.  */
   int num_core_regs = 0;