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

Jiang Jilin
2011-03-29T10:12:00Z

[-- Attachment #1: Type: text/plain, Size: 10305 bytes --]

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

[-- Attachment #2: 0001-Rewrite-the-codes-for-opcode-0x0f01-and-add-more-ins.patch --]
[-- Type: text/x-patch, Size: 9077 bytes --]

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