aboutsummaryrefslogtreecommitdiff
path: root/gdb/i386-tdep.c
diff options
context:
space:
mode:
authorLuis Machado <lgustavo@codesourcery.com>2017-02-06 03:12:00 -0600
committerLuis Machado <lgustavo@codesourcery.com>2017-02-06 03:12:00 -0600
commit20b477a75c00de06a92b9577fd74416699d2c37f (patch)
tree954421dcc9219afb9b6e186c59f47a9a4f9288a3 /gdb/i386-tdep.c
parent3f7b46f2daa6c396564d786bda9c81e66d4b9278 (diff)
downloadgdb-20b477a75c00de06a92b9577fd74416699d2c37f.zip
gdb-20b477a75c00de06a92b9577fd74416699d2c37f.tar.gz
gdb-20b477a75c00de06a92b9577fd74416699d2c37f.tar.bz2
[BZ 21005] Add support for Intel 64 rdrand and rdseed record/replay
This patch addresses BZ 21005, which is gdb failing to recognize an rdrand instruction. It enables support for both rdrand and rdseed and handles extended register addressing (R8~R15) for 16-bit, 32-bit and 64-bit. gdb/ChangeLog 2017-02-06 Luis Machado <lgustavo@codesourcery.com> * NEWS: Mention support for record/replay of Intel 64 rdrand and rdseed instructions. i386-tdep.c (i386_process_record): Handle Intel 64 rdrand and rseed. gdb/testsuite/ChangeLog: 2017-02-06 Luis Machado <lgustavo@codesourcery.com> * gdb.reverse/insn-reverse.c: Include insn-reverse-x86.c. * gdb.reverse/insn-reverse-x86.c: New file.
Diffstat (limited to 'gdb/i386-tdep.c')
-rw-r--r--gdb/i386-tdep.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index b86c623..bd87720 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -5501,14 +5501,36 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
- case 0x0fc7: /* cmpxchg8b */
+ case 0x0fc7: /* cmpxchg8b / rdrand / rdseed */
if (i386_record_modrm (&ir))
return -1;
if (ir.mod == 3)
{
- ir.addr -= 2;
- opcode = opcode << 8 | ir.modrm;
- goto no_support;
+ /* rdrand and rdseed use the 3 bits of the REG field of ModR/M as
+ an extended opcode. rdrand has bits 110 (/6) and rdseed
+ has bits 111 (/7). */
+ if (ir.reg == 6 || ir.reg == 7)
+ {
+ /* The storage register is described by the 3 R/M bits, but the
+ REX.B prefix may be used to give access to registers
+ R8~R15. In this case ir.rex_b + R/M will give us the register
+ in the range R8~R15.
+
+ REX.W may also be used to access 64-bit registers, but we
+ already record entire registers and not just partial bits
+ of them. */
+ I386_RECORD_FULL_ARCH_LIST_ADD_REG (ir.rex_b + ir.rm);
+ /* These instructions also set conditional bits. */
+ I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ }
+ else
+ {
+ /* We don't handle this particular instruction yet. */
+ ir.addr -= 2;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
}
I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);