[PATCH] Rewrite the codes for opcode 0x0f01 and add more instructions support

Jiang Jilin freephp@gmail.com
Tue Mar 29 12:07:00 GMT 2011


Michael,

Miss you!  I hope you could get the patch.

Sorry to Michael and Hui, it should be finished earlier.
No regression found after testing precord.exp.
Hui, please help review it.

2011-03-29  Jiang Jilin  <freephp@gmail.com>
      * i386-tdep.c (i386_process_record): Rewrite the codes for
      opcode 0x0f01 and add more instructions support
---
 gdb/i386-tdep.c |  281 ++++++++++++++++++++++++-------------------------------
 1 files changed, 122 insertions(+), 159 deletions(-)

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index c7ad3a6..94833cb 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -5802,174 +5802,137 @@ Do you want to stop the program?"),
    case 0x0f01:
      if (i386_record_modrm (&ir))
       return -1;
-      switch (ir.reg)
+      if (ir.mod == 3)
       {
-       case 0:  /* sgdt */
-         {
-           uint64_t addr64;
-
-           if (ir.mod == 3)
-             {
-               ir.addr -= 3;
-               opcode = opcode << 8 | ir.modrm;
-               goto no_support;
-             }
-           if (ir.override >= 0)
-             {
-                if (record_memory_query)
-                  {
-                   int q;
+         uint8_t reg_rm = (ir.reg << 4) | ir.rm;

-                    target_terminal_ours ();
-                    q = yquery (_("\
-Process record ignores the memory change of instruction at address %s\n\
-because it can't get the value of the segment register.\n\
-Do you want to stop the program?"),
-                                paddress (gdbarch, ir.orig_addr));
-                    target_terminal_inferior ();
-                    if (q)
-                      return -1;
-                  }
-             }
-           else
-             {
-               if (i386_record_lea_modrm_addr (&ir, &addr64))
-                 return -1;
-               if (record_arch_list_add_mem (addr64, 2))
-                 return -1;
-               addr64 += 2;
+         switch (reg_rm)
+           {
+              /* vmcall */
+              case 0x01:
+                /* vmlaunch */
+              case 0x02:
+                /* vmresume */
+              case 0x03:
+                /* vmxoff */
+              case 0x04:
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+                break;
+                /* monitor */
+              case 0x10:
+                break;
+                /* mwait */
+              case 0x11:
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+                break;
+                /* xgetbv */
+              case 0x20:
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+                break;
+                /* xsetbv */
+              case 0x21:
+                break;
+                /* swapgs */
+              case 0x70:
                if (ir.regmap[X86_RECORD_R8_REGNUM])
+                  I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+                else
                  {
-                    if (record_arch_list_add_mem (addr64, 8))
-                     return -1;
+                    ir.addr -= 3;
+                    opcode = opcode << 8 | ir.modrm;
+                    goto no_support;
                  }
-                else
+                break;
+                /* rdtscp */
+              case 0x71:
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+                I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+                break;
+              default:
+                /* smsw */
+                if (ir.reg == 4)
                  {
-                    if (record_arch_list_add_mem (addr64, 4))
-                     return -1;
+                    I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+                    break;
                  }
-             }
-         }
-         break;
-       case 1:
-         if (ir.mod == 3)
-           {
-             switch (ir.rm)
-               {
-               case 0:  /* monitor */
-                 break;
-               case 1:  /* mwait */
-                 I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
-                 break;
-               default:
-                 ir.addr -= 3;
-                 opcode = opcode << 8 | ir.modrm;
-                 goto no_support;
-                 break;
-               }
-           }
-         else
-           {
-             /* sidt */
-             if (ir.override >= 0)
-               {
-                  if (record_memory_query)
-                    {
-                     int q;
-
-                      target_terminal_ours ();
-                      q = yquery (_("\
-Process record ignores the memory change of instruction at address %s\n\
-because it can't get the value of the segment register.\n\
-Do you want to stop the program?"),
-                                  paddress (gdbarch, ir.orig_addr));
-                      target_terminal_inferior ();
-                      if (q)
-                        return -1;
-                    }
-               }
-             else
-               {
-                 uint64_t addr64;
+                /* lmsw */
+                else if (ir.reg == 6)
+                  break;

-                 if (i386_record_lea_modrm_addr (&ir, &addr64))
-                   return -1;
-                 if (record_arch_list_add_mem (addr64, 2))
-                   return -1;
-                 addr64 += 2;
-                  if (ir.regmap[X86_RECORD_R8_REGNUM])
-                    {
-                      if (record_arch_list_add_mem (addr64, 8))
-                       return -1;
-                    }
-                  else
-                    {
-                      if (record_arch_list_add_mem (addr64, 4))
-                       return -1;
-                    }
-               }
-           }
-         break;
-       case 2:  /* lgdt */
-         if (ir.mod == 3)
-           {
-             /* xgetbv */
-             if (ir.rm == 0)
-               {
-                 I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
-                 I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
-                 break;
-               }
-             /* xsetbv */
-             else if (ir.rm == 1)
-               break;
-           }
-       case 3:  /* lidt */
-         if (ir.mod == 3)
-           {
-             ir.addr -= 3;
-             opcode = opcode << 8 | ir.modrm;
-             goto no_support;
-           }
-         break;
-       case 4:  /* smsw */
-         if (ir.mod == 3)
-           {
-             if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
-               return -1;
-           }
-         else
-           {
-             ir.ot = OT_WORD;
-             if (i386_record_lea_modrm (&ir))
-               return -1;
-           }
-         I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
-         break;
-       case 6:  /* lmsw */
-         I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
-         break;
-       case 7:  /* invlpg */
-         if (ir.mod == 3)
+                ir.addr -= 3;
+                opcode = opcode << 8 | ir.modrm;
+                goto no_support;
+            }
+        }
+      else
+       {
+         switch (ir.reg)
           {
-             if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
-               I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
-             else
-               {
-                 ir.addr -= 3;
-                 opcode = opcode << 8 | ir.modrm;
-                 goto no_support;
-               }
-           }
-         else
-           I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
-         break;
-       default:
-         ir.addr -= 3;
-         opcode = opcode << 8 | ir.modrm;
-         goto no_support;
-         break;
-       }
+              /* sgdt */
+              case 0:
+                /* sidt */
+              case 1:
+                if (ir.override >= 0)
+                  {
+                    if (record_memory_query)
+                      {
+                        int q;
+
+                        target_terminal_ours ();
+                        q = yquery (_("\
+                              Process record ignores the memory change of \
+                              instruction at address %s\n\
+                              because it can't get the value of the segment \
+                              register.\n Do you want to stop the program?"),
+                            paddress (gdbarch, ir.orig_addr));
+                        target_terminal_inferior ();
+                        if (q)
+                          return -1;
+                      }
+                  }
+                else
+                  {
+                    uint64_t tmpu64;
+
+                    /* We have to store at least (4 + 2 = 6) bytes,
+                       or (8 + 2 = 10) bytes at most.  */
+                    if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+                      return -1;
+                    if (record_arch_list_add_mem (tmpu64, 6))
+                      return -1;
+                    tmpu64 += 6;
+                    if (ir.regmap[X86_RECORD_R8_REGNUM])
+                      {
+                        if (record_arch_list_add_mem (tmpu64, 4))
+                          return -1;
+                      }
+                  }
+                break;
+                /* lgdt */
+              case 2:
+                /* lidt */
+              case 3:
+                break;
+                /* smsw */
+              case 4:
+                ir.ot = OT_WORD;
+                if (i386_record_lea_modrm (&ir))
+                  return -1;
+                break;
+                /* lmsw */
+              case 6:
+                break;
+                /* invlpg */
+              case 7:
+                break;
+              default:
+                ir.addr -= 3;
+                opcode = opcode << 8 | ir.modrm;
+                goto no_support;
+            }
+        }
      break;

    case 0x0f08:    /* invd */
--
1.7.0.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Rewrite-the-codes-for-opcode-0x0f01-and-add-more-ins.patch
Type: text/x-patch
Size: 9077 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20110329/1b881a7b/attachment.bin>


More information about the Gdb-patches mailing list