diff options
author | Marcin Kościelnicki <koriakin@0x04.net> | 2016-02-06 18:17:07 +0100 |
---|---|---|
committer | Marcin Kościelnicki <koriakin@0x04.net> | 2016-02-10 15:30:31 +0100 |
commit | 62e5fd57bcdfb58eadd08ec430c4dfd742027d8e (patch) | |
tree | d338b40a312a2b92bd3c98ababb1d0df1ecb2040 | |
parent | e909d859f5635d66e79fef467da70d6090bfae1b (diff) | |
download | fsf-binutils-gdb-62e5fd57bcdfb58eadd08ec430c4dfd742027d8e.zip fsf-binutils-gdb-62e5fd57bcdfb58eadd08ec430c4dfd742027d8e.tar.gz fsf-binutils-gdb-62e5fd57bcdfb58eadd08ec430c4dfd742027d8e.tar.bz2 |
gdb/x86: Implement ax_pseudo_register_collect hook.
Makes "collect $ymm15" action work.
gdb/ChangeLog:
* amd64-tdep.c (amd64_ax_pseudo_register_collect): New function.
(amd64_init_abi): Fill ax_pseudo_register_collect hook.
* gdb/i386-tdep.c (i386_pseudo_register_read_into_value): Remove
misleading comment.
(i386_pseudo_register_write): Ditto.
(i386_ax_pseudo_register_collect): New function.
(i386_gdbarch_init): Fill ax_pseudo_register_collect hook.
* i386-tdep.h: Add i386_ax_pseudo_register_collect prototype.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 31 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 90 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 4 |
4 files changed, 130 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b32a301..05d6cd0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2016-02-10 Marcin Kościelnicki <koriakin@0x04.net> + * amd64-tdep.c (amd64_ax_pseudo_register_collect): New function. + (amd64_init_abi): Fill ax_pseudo_register_collect hook. + * gdb/i386-tdep.c (i386_pseudo_register_read_into_value): Remove + misleading comment. + (i386_pseudo_register_write): Ditto. + (i386_ax_pseudo_register_collect): New function. + (i386_gdbarch_init): Fill ax_pseudo_register_collect hook. + * i386-tdep.h: Add i386_ax_pseudo_register_collect prototype. + +2016-02-10 Marcin Kościelnicki <koriakin@0x04.net> + * tracefile-tfile.c (tfile_fetch_registers): Use g packet order instead of gdb order. diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index fae92b2..a62efde 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -455,6 +455,35 @@ amd64_pseudo_register_write (struct gdbarch *gdbarch, i386_pseudo_register_write (gdbarch, regcache, regnum, buf); } +/* Implement the 'ax_pseudo_register_collect' gdbarch method. */ + +static int +amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (i386_byte_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->al_regnum; + + if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS) + ax_reg_mask (ax, gpnum - AMD64_NUM_LOWER_BYTE_REGS); + else + ax_reg_mask (ax, gpnum); + return 0; + } + else if (i386_dword_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->eax_regnum; + + ax_reg_mask (ax, gpnum); + return 0; + } + else + return i386_ax_pseudo_register_collect (gdbarch, ax, regnum); +} + /* Register classes as defined in the psABI. */ @@ -2997,6 +3026,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_pseudo_register_read_value); set_gdbarch_pseudo_register_write (gdbarch, amd64_pseudo_register_write); + set_gdbarch_ax_pseudo_register_collect (gdbarch, + amd64_ax_pseudo_register_collect); set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name); diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index b706463..db4cd0a 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3419,9 +3419,6 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch, } else if (i386_byte_regnum_p (gdbarch, regnum)) { - /* Check byte pseudo registers last since this function will - be called from amd64_pseudo_register_read, which handles - byte pseudo registers differently. */ int gpnum = regnum - tdep->al_regnum; /* Extract (always little endian). We read both lower and @@ -3584,9 +3581,6 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } else if (i386_byte_regnum_p (gdbarch, regnum)) { - /* Check byte pseudo registers last since this function will - be called from amd64_pseudo_register_read, which handles - byte pseudo registers differently. */ int gpnum = regnum - tdep->al_regnum; /* Read ... We read both lower and upper registers. */ @@ -3603,6 +3597,88 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, internal_error (__FILE__, __LINE__, _("invalid regnum")); } } + +/* Implement the 'ax_pseudo_register_collect' gdbarch method. */ + +int +i386_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (i386_mmx_regnum_p (gdbarch, regnum)) + { + /* MMX to FPU register mapping depends on current TOS. Let's just + not care and collect everything... */ + int i; + + ax_reg_mask (ax, I387_FSTAT_REGNUM (tdep)); + for (i = 0; i < 8; i++) + ax_reg_mask (ax, I387_ST0_REGNUM (tdep) + i); + return 0; + } + else if (i386_bnd_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->bnd0_regnum; + ax_reg_mask (ax, I387_BND0R_REGNUM (tdep) + regnum); + return 0; + } + else if (i386_k_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->k0_regnum; + ax_reg_mask (ax, tdep->k0_regnum + regnum); + return 0; + } + else if (i386_zmm_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->zmm0_regnum; + if (regnum < num_lower_zmm_regs) + { + ax_reg_mask (ax, I387_XMM0_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm0h_regnum + regnum); + } + else + { + ax_reg_mask (ax, I387_XMM16_REGNUM (tdep) + regnum + - num_lower_zmm_regs); + ax_reg_mask (ax, I387_YMM16H_REGNUM (tdep) + regnum + - num_lower_zmm_regs); + } + ax_reg_mask (ax, tdep->zmm0h_regnum + regnum); + return 0; + } + else if (i386_ymm_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->ymm0_regnum; + ax_reg_mask (ax, I387_XMM0_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm0h_regnum + regnum); + return 0; + } + else if (i386_ymm_avx512_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->ymm16_regnum; + ax_reg_mask (ax, I387_XMM16_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm16h_regnum + regnum); + return 0; + } + else if (i386_word_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->ax_regnum; + + ax_reg_mask (ax, gpnum); + return 0; + } + else if (i386_byte_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->al_regnum; + + ax_reg_mask (ax, gpnum % 4); + return 0; + } + else + internal_error (__FILE__, __LINE__, _("invalid regnum")); + return 1; +} /* Return the register number of the register allocated by GCC after @@ -8423,6 +8499,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_read_value (gdbarch, i386_pseudo_register_read_value); set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write); + set_gdbarch_ax_pseudo_register_collect (gdbarch, + i386_ax_pseudo_register_collect); set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type); set_tdesc_pseudo_register_name (gdbarch, i386_pseudo_register_name); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 10d2772..770f59d 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -360,6 +360,10 @@ extern void i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int regnum, const gdb_byte *buf); +extern int i386_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, + int regnum); + /* Segment selectors. */ #define I386_SEL_RPL 0x0003 /* Requester's Privilege Level mask. */ #define I386_SEL_UPL 0x0003 /* User Privilige Level. */ |