[v2] Fix GDB: Initial r16-r31 support for Intel APX
Checks
Commit Message
---
gdb/amd64-tdep.c | 58 ++++++++++++++++++++++++++++++------------------
gdb/i386-tdep.h | 6 ++++-
2 files changed, 41 insertions(+), 23 deletions(-)
Comments
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.
@@ -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);
@@ -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;