[2/2,BZ,21005] Add support for Intel 64 rdrand and rdseed record/replay

Message ID 1485451129-16439-2-git-send-email-lgustavo@codesourcery.com
State New, archived
Headers

Commit Message

Luis Machado Jan. 26, 2017, 5:18 p.m. UTC
  The following 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.

I tested this by hand with quite a few lines of inline asm.  I thought we
had arch-specific tests in testsuite/, but it looks like we don't exercise
every little instruction with record/replay, so no testcase.  Let me know
if one is required.

Regression-tested on Ubuntu 16.04 x86-64.

Testsuite results are as follows:

    === gdb Summary ===

# of expected passes	159

OK?

gdb/ChangeLog

2017-01-26  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/NEWS        |  3 +++
 gdb/i386-tdep.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)
  

Comments

Eli Zaretskii Jan. 26, 2017, 7:35 p.m. UTC | #1
> From: Luis Machado <lgustavo@codesourcery.com>
> Date: Thu, 26 Jan 2017 11:18:49 -0600
> 
> The following 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.
> 
> I tested this by hand with quite a few lines of inline asm.  I thought we
> had arch-specific tests in testsuite/, but it looks like we don't exercise
> every little instruction with record/replay, so no testcase.  Let me know
> if one is required.
> 
> Regression-tested on Ubuntu 16.04 x86-64.
> 
> Testsuite results are as follows:
> 
>     === gdb Summary ===
> 
> # of expected passes	159
> 
> OK?
> 
> gdb/ChangeLog
> 
> 2017-01-26  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.

OK for the NEWS part.
  
Pedro Alves Feb. 1, 2017, 11:11 a.m. UTC | #2
On 01/26/2017 05:18 PM, Luis Machado wrote:
> The following patch addresses BZ 21005, which is gdb failing to
> recognize an rdrand instruction.

Suggest saying "this patch".  "following" won't make sense
when this sentence is part of the git log history.

> [....] I thought we
> had arch-specific tests in testsuite/, but it looks like we don't exercise
> every little instruction with record/replay, so no testcase.  Let me know
> if one is required.

This remark looks out of date?

> 
> OK?

Please remember to remove this, as it doesn't make sense to have
it in a commit log.

> 
> gdb/ChangeLog
> 
> 2017-01-26  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.

OK.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index 21e8cd3..0f63d9f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,9 @@ 
 
 *** Changes since GDB 7.12
 
+* GDB now supports recording and replaying rdrand and rdseed Intel 64
+  instructions.
+
 * Building GDB and GDBserver now requires a C++11 compiler.
 
   For example, GCC 4.8 or later.
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 8a4d59f..50327bb 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);