2011-03-29 Jiang Jilin * 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