--- amd64-linux-tdep.c | 2 amd64-tdep.c | 12 i386-tdep.c | 1427 ++++++++++++++++++++++++++++------------------------- i386-tdep.h | 33 + 4 files changed, 816 insertions(+), 658 deletions(-) --- a/amd64-linux-tdep.c +++ b/amd64-linux-tdep.c @@ -299,6 +299,8 @@ amd64_linux_init_abi (struct gdbarch_inf displaced_step_at_entry_point); set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); + + set_gdbarch_process_record (gdbarch, i386_process_record); } --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1975,6 +1975,16 @@ amd64_get_longjmp_target (struct frame_i return 1; } +static const int amd64_record_regmap[] = +{ + AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM, + AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM, + AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM, + AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM, + AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM, + AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM +}; + void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -2037,6 +2047,8 @@ amd64_init_abi (struct gdbarch_info info set_gdbarch_num_pseudo_regs (gdbarch, 0); tdep->mm0_regnum = -1; + tdep->record_regmap = amd64_record_regmap; + set_gdbarch_dummy_id (gdbarch, amd64_dummy_id); frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind); --- a/i386-tdep.c +++ b/i386-tdep.c @@ -2697,6 +2697,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2722,6 +2723,11 @@ struct i386_record_s uint8_t modrm; uint8_t mod, reg, rm; int ot; + uint8_t rex_x; + uint8_t rex_b; + int rip_offset; + int popl_esp_hack; + const int *regmap; }; /* Parse "modrm" part in current memory address that irp->addr point to @@ -2751,11 +2757,12 @@ i386_record_modrm (struct i386_record_s Return -1 if something wrong. */ static int -i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr) +i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr) { uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2779,9 +2786,10 @@ i386_record_lea_modrm_addr (struct i386_ } irp->addr++; scale = (tmpu8 >> 6) & 3; - index = ((tmpu8 >> 3) & 7); + index = ((tmpu8 >> 3) & 7) | irp->rex_x; base = (tmpu8 & 7); } + base |= irp->rex_b; switch (irp->mod) { @@ -2789,7 +2797,7 @@ i386_record_lea_modrm_addr (struct i386_ if ((base & 7) == 5) { base = 0xff; - if (target_read_memory (irp->addr, (gdb_byte *) addr, 4)) + if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4)) { if (record_debug) printf_unfiltered (_("Process record: error reading " @@ -2798,6 +2806,9 @@ i386_record_lea_modrm_addr (struct i386_ return -1; } irp->addr += 4; + *addr = tmpi32; + if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib) + *addr += irp->addr + irp->rip_offset; } else { @@ -2814,10 +2825,10 @@ i386_record_lea_modrm_addr (struct i386_ return -1; } irp->addr++; - *addr = (int8_t) tmpu8; + *addr = (int8_t)tmpu8; break; case 2: - if (target_read_memory (irp->addr, (gdb_byte *) addr, 4)) + if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4)) { if (record_debug) printf_unfiltered (_("Process record: error reading memory " @@ -2825,21 +2836,34 @@ i386_record_lea_modrm_addr (struct i386_ paddr_nz (irp->addr)); return -1; } + *addr = tmpi32; irp->addr += 4; break; } + tmpulongest = 0; if (base != 0xff) - { - regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32); - *addr += tmpu32; + { + if (base == 4 && irp->popl_esp_hack) + *addr += irp->popl_esp_hack; + regcache_raw_read_unsigned (irp->regcache, irp->regmap[base], + &tmpulongest); } + if (irp->aflag == 2) + { + *addr += tmpulongest; + } + else + *addr = (uint32_t)(tmpulongest + *addr); - /* XXX: index == 4 is always invalid */ if (havesib && (index != 4 || scale != 0)) { - regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32); - *addr += tmpu32 << scale; + regcache_raw_read_unsigned (irp->regcache, irp->regmap[index], + &tmpulongest); + if (irp->aflag == 2) + *addr += tmpulongest << scale; + else + *addr = (uint32_t)(*addr + (tmpulongest << scale)); } } else @@ -2851,7 +2875,7 @@ i386_record_lea_modrm_addr (struct i386_ if (irp->rm == 6) { if (target_read_memory - (irp->addr, (gdb_byte *) & tmpu16, 2)) + (irp->addr, (gdb_byte *)&tmpi16, 2)) { if (record_debug) printf_unfiltered (_("Process record: error reading " @@ -2860,7 +2884,7 @@ i386_record_lea_modrm_addr (struct i386_ return -1; } irp->addr += 2; - *addr = (int16_t) tmpu16; + *addr = tmpi16; irp->rm = 0; goto no_rm; } @@ -2879,10 +2903,10 @@ i386_record_lea_modrm_addr (struct i386_ return -1; } irp->addr++; - *addr = (int8_t) tmpu8; + *addr = (int8_t)tmpu8; break; case 2: - if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2)) + if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2)) { if (record_debug) printf_unfiltered (_("Process record: error reading memory " @@ -2891,63 +2915,75 @@ i386_record_lea_modrm_addr (struct i386_ return -1; } irp->addr += 2; - *addr = (int16_t) tmpu16; + *addr = tmpi16; break; } switch (irp->rm) { case 0: - regcache_raw_read (irp->regcache, I386_EBX_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; - regcache_raw_read (irp->regcache, I386_ESI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBX_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_RESI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 1: - regcache_raw_read (irp->regcache, I386_EBX_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; - regcache_raw_read (irp->regcache, I386_EDI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBX_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 2: - regcache_raw_read (irp->regcache, I386_EBP_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; - regcache_raw_read (irp->regcache, I386_ESI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBP_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_RESI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 3: - regcache_raw_read (irp->regcache, I386_EBP_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; - regcache_raw_read (irp->regcache, I386_EDI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBP_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 4: - regcache_raw_read (irp->regcache, I386_ESI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_RESI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 5: - regcache_raw_read (irp->regcache, I386_EDI_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 6: - regcache_raw_read (irp->regcache, I386_EBP_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBP_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; case 7: - regcache_raw_read (irp->regcache, I386_EBX_REGNUM, - (gdb_byte *) & tmpu32); - *addr += tmpu32; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_REBX_REGNUM], + &tmpulongest); + *addr = (uint32_t)(*addr + tmpulongest); break; } *addr &= 0xffff; @@ -2964,9 +3000,9 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - uint32_t addr; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -2985,10 +3021,36 @@ i386_record_lea_modrm (struct i386_recor return 0; } +/* Record the push operation to "record_arch_list". + Return -1 if something wrong. */ + +static int +i386_record_push (struct i386_record_s *irp, int size) +{ + ULONGEST tmpulongest; + + if (record_arch_list_add_reg (irp->regcache, + irp->regmap[X86_RECORD_RESP_REGNUM])) + return -1; + regcache_raw_read_unsigned (irp->regcache, + irp->regmap[X86_RECORD_RESP_REGNUM], + &tmpulongest); + if (record_arch_list_add_mem ((CORE_ADDR)tmpulongest - size, size)) + return -1; + + return 0; +} + /* Parse the current instruction and record the values of the registers and memory that will be changed in current instruction to "record_arch_list". Return -1 if something wrong. */ +#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \ + do { \ + if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \ + return -1; \ + } while (0) + int i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr) @@ -2997,14 +3059,20 @@ i386_process_record (struct gdbarch *gdb uint8_t tmpu8; uint16_t tmpu16; uint32_t tmpu32; + ULONGEST tmpulongest; uint32_t opcode; struct i386_record_s ir; + int rex = 0; + uint8_t rex_w = -1; + uint8_t rex_r = 0; memset (&ir, 0, sizeof (struct i386_record_s)); ir.regcache = regcache; ir.addr = addr; ir.aflag = 1; ir.dflag = 1; + ir.override = -1; + ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3035,22 +3103,22 @@ i386_process_record (struct gdbarch *gdb prefixes |= PREFIX_LOCK; break; case 0x2e: - ir.override = I386_CS_REGNUM; + ir.override = X86_RECORD_CS_REGNUM; break; case 0x36: - ir.override = I386_SS_REGNUM; + ir.override = X86_RECORD_SS_REGNUM; break; case 0x3e: - ir.override = I386_DS_REGNUM; + ir.override = X86_RECORD_DS_REGNUM; break; case 0x26: - ir.override = I386_ES_REGNUM; + ir.override = X86_RECORD_ES_REGNUM; break; case 0x64: - ir.override = I386_FS_REGNUM; + ir.override = X86_RECORD_FS_REGNUM; break; case 0x65: - ir.override = I386_GS_REGNUM; + ir.override = X86_RECORD_GS_REGNUM; break; case 0x66: prefixes |= PREFIX_DATA; @@ -3058,16 +3126,51 @@ i386_process_record (struct gdbarch *gdb case 0x67: prefixes |= PREFIX_ADDR; break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + /* REX */ + rex = 1; + rex_w = (tmpu8 >> 3) & 1; + rex_r = (tmpu8 & 0x4) << 1; + ir.rex_x = (tmpu8 & 0x2) << 2; + ir.rex_b = (tmpu8 & 0x1) << 3; + } + break; default: goto out_prefixes; break; } } out_prefixes: - if (prefixes & PREFIX_DATA) - ir.dflag ^= 1; + if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1) + { + ir.dflag = 2; + } + else + { + if (prefixes & PREFIX_DATA) + ir.dflag ^= 1; + } if (prefixes & PREFIX_ADDR) ir.aflag ^= 1; + else if (ir.regmap[X86_RECORD_R8_REGNUM]) + ir.aflag = 2; /* now check op code */ opcode = (uint32_t) tmpu8; @@ -3157,30 +3260,28 @@ reswitch: } else { - if (ir.ot == OT_BYTE) + ir.rm |= ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } break; /* OP Gv, Ev */ case 1: if (i386_record_modrm (&ir)) return -1; - if (ir.ot == OT_BYTE) + ir.reg |= rex_r; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); break; /* OP A, Iv */ case 2: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); break; } } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* GRP1 */ @@ -3200,17 +3301,17 @@ reswitch: if (ir.mod != 3) { + if (opcode == 0x83) + ir.rip_offset = 1; + else + ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot); if (i386_record_lea_modrm (&ir)) return -1; } else - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* inv */ @@ -3231,10 +3332,8 @@ reswitch: case 0x4d: case 0x4e: case 0x4f: - if (record_arch_list_add_reg (ir.regcache, opcode & 7)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* GRP3 */ @@ -3247,28 +3346,17 @@ reswitch: if (i386_record_modrm (&ir)) return -1; + if (ir.mod != 3 && ir.reg == 0) + ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot); + switch (ir.reg) { /* test */ case 0: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* not */ case 2: - if (ir.mod != 3) - { - if (i386_record_lea_modrm (&ir)) - return -1; - } - else - { - if (ir.ot == OT_BYTE) - ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } - break; /* neg */ case 3: if (ir.mod != 3) @@ -3278,13 +3366,14 @@ reswitch: } else { - if (ir.ot == OT_BYTE) + ir.rm |= ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + /* neg */ + if (ir.reg == 3) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* mul */ case 4: @@ -3294,15 +3383,10 @@ reswitch: case 6: /* idiv */ case 7: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); if (ir.ot != OT_BYTE) - { - if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM)) - return -1; - } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; default: ir.addr -= 2; @@ -3316,10 +3400,6 @@ reswitch: case 0xfe: /* GRP5 */ case 0xff: - if ((opcode & 1) == 0) - ir.ot = OT_BYTE; - else - ir.ot = ir.dflag + OT_WORD; if (i386_record_modrm (&ir)) return -1; if (ir.reg >= 2 && opcode == 0xfe) @@ -3328,13 +3408,16 @@ reswitch: opcode = opcode << 8 | ir.modrm; goto no_support; } - switch (ir.reg) { /* inc */ case 0: /* dec */ case 1: + if ((opcode & 1) == 0) + ir.ot = OT_BYTE; + else + ir.ot = ir.dflag + OT_WORD; if (ir.mod != 3) { if (i386_record_lea_modrm (&ir)) @@ -3342,42 +3425,40 @@ reswitch: } else { - if (ir.ot == OT_BYTE) + ir.rm |= ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* call */ case 2: - /* push */ - case 6: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1)))) + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* lcall */ case 3: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2)))) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM); + if (i386_record_push (&ir, 1 << (ir.dflag + 2))) return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* jmp */ case 4: /* ljmp */ case 5: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + /* push */ + case 6: + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; default: ir.addr -= 2; @@ -3392,22 +3473,18 @@ reswitch: case 0x85: case 0xa8: case 0xa9: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* CWDE/CBW */ case 0x98: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); break; /* CDQ/CWD */ case 0x99: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM); break; /* imul */ @@ -3417,12 +3494,15 @@ reswitch: ir.ot = ir.dflag + OT_WORD; if (i386_record_modrm (&ir)) return -1; - if (ir.ot == OT_BYTE) + if (opcode == 0x69) + ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot); + else if (opcode == 0x6b) + ir.rip_offset = 1; + ir.reg |= rex_r; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* xadd */ @@ -3434,28 +3514,25 @@ reswitch: ir.ot = ir.dflag + OT_WORD; if (i386_record_modrm (&ir)) return -1; + ir.reg |= rex_r; if (ir.mod == 3) { - if (ir.ot == OT_BYTE) + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; - if (ir.ot == OT_BYTE) + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } else { if (i386_record_lea_modrm (&ir)) return -1; - if (ir.ot == OT_BYTE) + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* cmpxchg */ @@ -3469,22 +3546,19 @@ reswitch: return -1; if (ir.mod == 3) { - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (ir.ot == OT_BYTE) + ir.reg |= rex_r; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); } else { - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); if (i386_record_lea_modrm (&ir)) return -1; } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* cmpxchg8b */ @@ -3497,14 +3571,11 @@ reswitch: opcode = opcode << 8 | ir.modrm; goto no_support; } - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM); if (i386_record_lea_modrm (&ir)) return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* push */ @@ -3518,6 +3589,12 @@ reswitch: case 0x57: case 0x68: case 0x6a: + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; + break; + /* push es */ case 0x06: /* push cs */ @@ -3526,16 +3603,36 @@ reswitch: case 0x16: /* push ds */ case 0x1e: + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; + break; + /* push fs */ case 0x0fa0: /* push gs */ case 0x0fa8: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 2; + goto no_support; + } + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1)))) + break; + + /* pusha */ + case 0x60: + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + if (i386_record_push (&ir, 1 << (ir.dflag + 4))) return -1; break; @@ -3548,113 +3645,103 @@ reswitch: case 0x5d: case 0x5e: case 0x5f: - ir.ot = ir.dflag + OT_WORD; - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (ir.ot == OT_BYTE) - opcode &= 0x3; - if (record_arch_list_add_reg (ir.regcache, opcode & 0x7)) - return -1; - break; - - /* pusha */ - case 0x60: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4)))) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b); break; /* popa */ case 0x61: - for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++) - { - if (record_arch_list_add_reg (ir.regcache, tmpu8)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; } + for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM; + tmpu8++) + I386_RECORD_ARCH_LIST_ADD_REG (tmpu8); break; /* pop */ case 0x8f: - ir.ot = ir.dflag + OT_WORD; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + ir.ot = ir.dflag ? OT_QUAD : OT_WORD; + else + ir.ot = ir.dflag + OT_WORD; if (i386_record_modrm (&ir)) return -1; if (ir.mod == 3) - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); else { if (i386_record_lea_modrm (&ir)) return -1; } - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); break; /* enter */ case 0xc8: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1)))) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM); + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) return -1; break; /* leave */ case 0xc9: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM); break; /* pop es */ case 0x07: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* pop ss */ case 0x17: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* pop ds */ case 0x1f: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* pop fs */ case 0x0fa1: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* pop gs */ case 0x0fa9: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* mov */ @@ -3672,19 +3759,21 @@ reswitch: if (ir.mod != 3) { + if (opcode == 0xc6 || opcode == 0xc7) + ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot); if (i386_record_lea_modrm (&ir)) return -1; } else { - if (ir.ot == OT_BYTE) + if (opcode == 0xc6 || opcode == 0xc7) + ir.rm |= ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; break; + /* mov */ case 0x8a: case 0x8b: @@ -3692,40 +3781,55 @@ reswitch: ir.ot = OT_BYTE; else ir.ot = ir.dflag + OT_WORD; - if (i386_record_modrm (&ir)) return -1; - - if (ir.ot == OT_BYTE) + ir.reg |= rex_r; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); + break; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) + /* mov seg */ + case 0x8c: + if (i386_record_modrm (&ir)) return -1; + if (ir.reg > 5) + { + ir.addr -= 2; + opcode = opcode << 8 | ir.modrm; + goto no_support; + } + + if (ir.mod == 3) + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); + else + { + ir.ot = OT_WORD; + if (i386_record_lea_modrm (&ir)) + return -1; + } break; /* mov seg */ case 0x8e: if (i386_record_modrm (&ir)) return -1; - switch (ir.reg) { case 0: - tmpu8 = I386_ES_REGNUM; + tmpu8 = X86_RECORD_ES_REGNUM; break; case 2: - tmpu8 = I386_SS_REGNUM; + tmpu8 = X86_RECORD_SS_REGNUM; break; case 3: - tmpu8 = I386_DS_REGNUM; + tmpu8 = X86_RECORD_DS_REGNUM; break; case 4: - tmpu8 = I386_FS_REGNUM; + tmpu8 = X86_RECORD_FS_REGNUM; break; case 5: - tmpu8 = I386_GS_REGNUM; + tmpu8 = X86_RECORD_GS_REGNUM; break; default: ir.addr -= 2; @@ -3733,38 +3837,8 @@ reswitch: goto no_support; break; } - if (record_arch_list_add_reg (ir.regcache, tmpu8)) - return -1; - - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; - break; - - /* mov seg */ - case 0x8c: - if (i386_record_modrm (&ir)) - return -1; - if (ir.reg > 5) - { - ir.addr -= 2; - opcode = opcode << 8 | ir.modrm; - goto no_support; - } - - if (ir.mod == 3) - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } - else - { - ir.ot = OT_WORD; - if (i386_record_lea_modrm (&ir)) - return -1; - } - - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (tmpu8); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* movzbS */ @@ -3777,8 +3851,7 @@ reswitch: case 0x0fbf: if (i386_record_modrm (&ir)) return -1; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r); break; /* lea */ @@ -3791,12 +3864,11 @@ reswitch: opcode = opcode << 8 | ir.modrm; goto no_support; } - ir.ot = ir.dflag; - if (ir.ot == OT_BYTE) + ir.reg |= rex_r; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); break; /* mov EAX */ @@ -3804,62 +3876,71 @@ reswitch: case 0xa1: /* xlat */ case 0xd7: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); break; /* mov EAX */ case 0xa2: case 0xa3: - { - uint32_t addr; - - if (ir.override) - { - if (record_debug) - printf_unfiltered (_("Process record ignores the memory change " - "of instruction at address 0x%s because " - "it can't get the value of the segment " - "register.\n"), - paddr_nz (ir.addr)); - } - else - { - if ((opcode & 1) == 0) - ir.ot = OT_BYTE; - else - ir.ot = ir.dflag + OT_WORD; - if (ir.aflag) - { - if (target_read_memory - (ir.addr, (gdb_byte *) & addr, 4)) - { - if (record_debug) - printf_unfiltered (_("Process record: error reading " - "memory at addr 0x%s len = 4.\n"), - paddr_nz (ir.addr)); - return -1; - } - ir.addr += 4; - } - else - { - if (target_read_memory - (ir.addr, (gdb_byte *) & tmpu16, 4)) - { - if (record_debug) - printf_unfiltered (_("Process record: error reading " - "memory at addr 0x%s len = 4.\n"), - paddr_nz (ir.addr)); - return -1; - } - ir.addr += 2; - addr = tmpu16; - } - if (record_arch_list_add_mem (addr, 1 << ir.ot)) - return -1; - } - } + if (ir.override >= 0) + { + if (record_debug) + printf_unfiltered (_("Process record ignores the memory change " + "of instruction at address 0x%s because " + "it can't get the value of the segment " + "register.\n"), + paddr_nz (ir.addr)); + } + else + { + if ((opcode & 1) == 0) + ir.ot = OT_BYTE; + else + ir.ot = ir.dflag + OT_WORD; + if (ir.aflag == 2) + { + if (target_read_memory + (ir.addr, (gdb_byte *)&addr, 8)) + { + if (record_debug) + printf_unfiltered (_("Process record: error reading " + "memory at addr 0x%s len = 8.\n"), + paddr_nz (ir.addr)); + return -1; + } + ir.addr += 8; + } + else if (ir.aflag) + { + if (target_read_memory + (ir.addr, (gdb_byte *)&tmpu32, 4)) + { + if (record_debug) + printf_unfiltered (_("Process record: error reading " + "memory at addr 0x%s len = 4.\n"), + paddr_nz (ir.addr)); + return -1; + } + ir.addr += 4; + addr = tmpu32; + } + else + { + if (target_read_memory + (ir.addr, (gdb_byte *)&tmpu16, 2)) + { + if (record_debug) + printf_unfiltered (_("Process record: error reading " + "memory at addr 0x%s len = 2.\n"), + paddr_nz (ir.addr)); + return -1; + } + ir.addr += 2; + addr = tmpu16; + } + if (record_arch_list_add_mem (addr, 1 << ir.ot)) + return -1; + } break; /* mov R, Ib */ @@ -3871,8 +3952,9 @@ reswitch: case 0xb5: case 0xb6: case 0xb7: - if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ? + ((opcode & 0x7) | ir.rex_b) : + ((opcode & 0x7) & 0x3)); break; /* mov R, Iv */ @@ -3884,8 +3966,7 @@ reswitch: case 0xbd: case 0xbe: case 0xbf: - if (record_arch_list_add_reg (ir.regcache, opcode & 0x7)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b); break; /* xchg R, EAX */ @@ -3896,10 +3977,8 @@ reswitch: case 0x95: case 0x96: case 0x97: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, opcode & 0x7)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7); break; /* xchg Ev, Gv */ @@ -3909,33 +3988,35 @@ reswitch: ir.ot = OT_BYTE; else ir.ot = ir.dflag + OT_WORD; - if (i386_record_modrm (&ir)) return -1; - if (ir.mod == 3) { - if (ir.ot == OT_BYTE) + ir.rm != ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } else { if (i386_record_lea_modrm (&ir)) return -1; } - - if (ir.ot == OT_BYTE) + ir.reg |= rex_r; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); break; /* les Gv */ case 0xc4: /* lds Gv */ case 0xc5: + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } /* lss Gv */ case 0x0fb2: /* lfs Gv */ @@ -3953,35 +4034,32 @@ reswitch: opcode = opcode << 8 | ir.modrm; goto no_support; } - switch (opcode) { /* les Gv */ case 0xc4: - tmpu8 = I386_ES_REGNUM; + tmpu8 = X86_RECORD_ES_REGNUM; break; /* lds Gv */ case 0xc5: - tmpu8 = I386_DS_REGNUM; + tmpu8 = X86_RECORD_DS_REGNUM; break; /* lss Gv */ case 0x0fb2: - tmpu8 = I386_SS_REGNUM; + tmpu8 = X86_RECORD_SS_REGNUM; break; /* lfs Gv */ case 0x0fb4: - tmpu8 = I386_FS_REGNUM; + tmpu8 = X86_RECORD_FS_REGNUM; break; /* lgs Gv */ case 0x0fb5: - tmpu8 = I386_GS_REGNUM; + tmpu8 = X86_RECORD_GS_REGNUM; break; } - if (record_arch_list_add_reg (ir.regcache, tmpu8)) - return -1; - - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (tmpu8); + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* shifts */ @@ -3995,10 +4073,8 @@ reswitch: ir.ot = OT_BYTE; else ir.ot = ir.dflag + OT_WORD; - if (i386_record_modrm (&ir)) return -1; - if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3)) { if (i386_record_lea_modrm (&ir)) @@ -4006,14 +4082,12 @@ reswitch: } else { - if (ir.ot == OT_BYTE) + ir.rm |= ir.rex_b; + if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM]) ir.rm &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm); } - - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; case 0x0fa4: @@ -4050,9 +4124,9 @@ reswitch: if (ir.mod != 3) { /* memory */ - uint32_t addr; + uint64_t tmpu64; - if (i386_record_lea_modrm_addr (&ir, &addr)) + if (i386_record_lea_modrm_addr (&ir, &tmpu64)) return -1; switch (ir.reg) { @@ -4112,16 +4186,16 @@ reswitch: switch (ir.reg >> 4) { case 0: - if (record_arch_list_add_mem (addr, 4)) + if (record_arch_list_add_mem (tmpu64, 4)) return -1; break; case 2: - if (record_arch_list_add_mem (addr, 8)) + if (record_arch_list_add_mem (tmpu64, 8)) return -1; break; case 3: default: - if (record_arch_list_add_mem (addr, 2)) + if (record_arch_list_add_mem (tmpu64, 2)) return -1; break; } @@ -4131,16 +4205,16 @@ reswitch: { case 0: case 1: - if (record_arch_list_add_mem (addr, 4)) + if (record_arch_list_add_mem (tmpu64, 4)) return -1; break; case 2: - if (record_arch_list_add_mem (addr, 8)) + if (record_arch_list_add_mem (tmpu64, 8)) return -1; break; case 3: default: - if (record_arch_list_add_mem (addr, 2)) + if (record_arch_list_add_mem (tmpu64, 2)) return -1; break; } @@ -4157,43 +4231,43 @@ reswitch: case 0x0e: if (ir.dflag) { - if (record_arch_list_add_mem (addr, 28)) + if (record_arch_list_add_mem (tmpu64, 28)) return -1; } else { - if (record_arch_list_add_mem (addr, 14)) + if (record_arch_list_add_mem (tmpu64, 14)) return -1; } break; case 0x0f: case 0x2f: - if (record_arch_list_add_mem (addr, 2)) + if (record_arch_list_add_mem (tmpu64, 2)) return -1; break; case 0x1f: case 0x3e: - if (record_arch_list_add_mem (addr, 10)) + if (record_arch_list_add_mem (tmpu64, 10)) return -1; break; case 0x2e: if (ir.dflag) { - if (record_arch_list_add_mem (addr, 28)) + if (record_arch_list_add_mem (tmpu64, 28)) return -1; - addr += 28; + tmpu64 += 28; } else { - if (record_arch_list_add_mem (addr, 14)) + if (record_arch_list_add_mem (tmpu64, 14)) return -1; - addr += 14; + tmpu64 += 14; } - if (record_arch_list_add_mem (addr, 80)) + if (record_arch_list_add_mem (tmpu64, 80)) return -1; break; case 0x3f: - if (record_arch_list_add_mem (addr, 8)) + if (record_arch_list_add_mem (tmpu64, 8)) return -1; break; default: @@ -4215,123 +4289,88 @@ reswitch: /* insS */ case 0x6c: case 0x6d: - { - uint32_t addr; - - if ((opcode & 1) == 0) - ir.ot = OT_BYTE; - else - ir.ot = ir.dflag + OT_WORD; - if (opcode == 0xa4 || opcode == 0xa5) - { - if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM)) - return -1; - } - if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM)) - return -1; - - regcache_raw_read (ir.regcache, I386_EDI_REGNUM, - (gdb_byte *) & addr); - if (!ir.aflag) - { - addr &= 0xffff; - /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */ - if (record_debug) - printf_unfiltered (_("Process record ignores the memory change " - "of instruction at address 0x%s because " - "it can't get the value of the segment " - "register.\n"), - paddr_nz (ir.addr)); - } - - if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) - { - uint32_t count; - - regcache_raw_read (ir.regcache, I386_ECX_REGNUM, - (gdb_byte *) & count); - if (!ir.aflag) - count &= 0xffff; - - regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM, - (gdb_byte *) & tmpu32); - if ((tmpu32 >> 10) & 0x1) - addr -= (count - 1) * (1 << ir.ot); - - if (ir.aflag) - { - if (record_arch_list_add_mem (addr, count * (1 << ir.ot))) - return -1; - } + if ((opcode & 1) == 0) + ir.ot = OT_BYTE; + else + ir.ot = ir.dflag + OT_WORD; + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[X86_RECORD_REDI_REGNUM], + &tmpulongest); + if (!ir.aflag) + { + tmpulongest &= 0xffff; + /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */ + if (record_debug) + printf_unfiltered (_("Process record ignores the memory change " + "of instruction at address 0x%s because " + "it can't get the value of the segment " + "register.\n"), + paddr_nz (ir.addr)); + } + if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) + { + ULONGEST count, eflags; + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[X86_RECORD_REDI_REGNUM], + &count); + if (!ir.aflag) + count &= 0xffff; + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[X86_RECORD_EFLAGS_REGNUM], + &eflags); + if ((eflags >> 10) & 0x1) + tmpulongest -= (count - 1) * (1 << ir.ot); + if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot))) + return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + } + else + { + if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot)) + return -1; + } + if (opcode == 0xa4 || opcode == 0xa5) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - } - else - { - if (ir.aflag) - { - if (record_arch_list_add_mem (addr, 1 << ir.ot)) - return -1; - } - } - } + /* cmpsS */ + case 0xa6: + case 0xa7: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM); + if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* lodsS */ case 0xac: case 0xad: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM)) - return -1; - if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) - { - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - } - break; - - /* outsS */ - case 0x6e: - case 0x6f: - if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) - { - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* scasS */ case 0xae: case 0xaf: - if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) - { - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; - /* cmpsS */ - case 0xa6: - case 0xa7: - if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM)) - return -1; + /* outsS */ + case 0x6e: + case 0x6f: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) - { - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* port I/O */ @@ -4339,8 +4378,8 @@ reswitch: case 0xe5: case 0xec: case 0xed: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); break; case 0xe6: @@ -4354,48 +4393,32 @@ reswitch: case 0xc2: /* ret */ case 0xc3: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + /* lret im */ case 0xca: /* lret */ case 0xcb: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM)) - return -1; - break; - /* iret */ case 0xcf: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* call im */ case 0xe8: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1)))) - return -1; + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; /* lcall im */ case 0x9a: - if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2)))) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM); + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; /* jmp im */ @@ -4457,14 +4480,13 @@ reswitch: case 0x0f9d: case 0x0f9e: case 0x0f9f: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); ir.ot = OT_BYTE; if (i386_record_modrm (&ir)) return -1; if (ir.mod == 3) - { - if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b): + (ir.rm & 0x3)); else { if (i386_record_lea_modrm (&ir)) @@ -4491,34 +4513,33 @@ reswitch: case 0x0f4f: if (i386_record_modrm (&ir)) return -1; + ir.reg |= rex_r; if (ir.dflag == OT_BYTE) ir.reg &= 0x3; - if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg); break; /* flags */ /* pushf */ case 0x9c: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - regcache_raw_read (ir.regcache, I386_ESP_REGNUM, - (gdb_byte *) & tmpu32); - if (record_arch_list_add_mem - ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1)))) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; /* popf */ case 0x9d: - if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* sahf */ case 0x9e: + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } /* cmc */ case 0xf5: /* clc */ @@ -4529,66 +4550,95 @@ reswitch: case 0xfc: /* std */ case 0xfd: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* lahf */ case 0x9f: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); break; /* bit operations */ /* bt/bts/btr/btc Gv, im */ case 0x0fba: - /* bts */ - case 0x0fab: - /* btr */ - case 0x0fb3: - /* btc */ - case 0x0fbb: ir.ot = ir.dflag + OT_WORD; if (i386_record_modrm (&ir)) return -1; if (ir.reg < 4) { - ir.addr -= 3; + ir.addr -= 2; opcode = opcode << 8 | ir.modrm; goto no_support; } - ir.reg -= 4; - if (ir.reg != 0) + if (ir.reg != 4) { - if (ir.mod != 3) - { - if (i386_record_lea_modrm (&ir)) - return -1; - } + if (ir.mod ==3) + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); else { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) + if (i386_record_lea_modrm (&ir)) return -1; } } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* bt Gv, Ev */ case 0x0fa3: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + + /* bts */ + case 0x0fab: + /* btr */ + case 0x0fb3: + /* btc */ + case 0x0fbb: + ir.ot = ir.dflag + OT_WORD; + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3) + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); + else + { + uint64_t tmpu64; + if (i386_record_lea_modrm_addr (&ir, &tmpu64)) + return -1; + regcache_raw_read_unsigned (ir.regcache, + ir.regmap[ir.reg | rex_r], + &tmpulongest); + switch (ir.dflag) + { + case 0: + tmpu64 += ((int16_t)tmpulongest >> 4)<< 4; + break; + case 1: + tmpu64 += ((int32_t)tmpulongest >> 5)<< 5; + break; + case 2: + tmpu64 += ((int64_t)tmpulongest >> 6)<< 6; + break; + } + if (record_arch_list_add_mem (tmpu64, 1 << ir.ot)) + return -1; + if (i386_record_lea_modrm (&ir)) + return -1; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* bsf */ case 0x0fbc: /* bsr */ case 0x0fbd: - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* bcd */ @@ -4604,10 +4654,13 @@ reswitch: case 0xd4: /* aad */ case 0xd5: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* misc */ @@ -4699,16 +4752,18 @@ reswitch: case 0x0fcd: case 0x0fce: case 0x0fcf: - if (record_arch_list_add_reg (ir.regcache, opcode & 7)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b); break; /* salc */ case 0xd6: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* loopnz */ @@ -4719,8 +4774,8 @@ reswitch: case 0xe2: /* jecxz */ case 0xe3: - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* wrmsr */ @@ -4751,6 +4806,11 @@ reswitch: case 0x0f34: { int ret; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 2; + goto no_support; + } if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL) { printf_unfiltered (_("Process record doesn't support " @@ -4772,16 +4832,28 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + break; + + /* sysret */ + case 0x0f07: + printf_unfiltered (_("Process record doesn't support " + "instruction sysret.\n")); + ir.addr -= 2; + goto no_support; + break; + /* cpuid */ case 0x0fa2: - if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM)) - return -1; + 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); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBX_REGNUM); break; /* hlt */ @@ -4802,10 +4874,7 @@ reswitch: /* str */ case 1: if (ir.mod == 3) - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); else { ir.ot = OT_WORD; @@ -4822,8 +4891,7 @@ reswitch: case 4: /* verw */ case 5: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; default: ir.addr -= 3; @@ -4841,7 +4909,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -4849,8 +4917,7 @@ reswitch: opcode = opcode << 8 | ir.modrm; goto no_support; } - - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -4862,13 +4929,21 @@ reswitch: } else { - if (i386_record_lea_modrm_addr (&ir, &addr)) - return -1; - if (record_arch_list_add_mem (addr, 2)) + if (i386_record_lea_modrm_addr (&ir, &tmpu64)) return -1; - addr += 2; - if (record_arch_list_add_mem (addr, 4)) + if (record_arch_list_add_mem (tmpu64, 2)) return -1; + tmpu64 += 2; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + if (record_arch_list_add_mem (tmpu64, 8)) + return -1; + } + else + { + if (record_arch_list_add_mem (tmpu64, 4)) + return -1; + } } } break; @@ -4882,8 +4957,7 @@ reswitch: break; /* mwait */ case 1: - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; default: ir.addr -= 3; @@ -4895,7 +4969,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -4907,15 +4981,23 @@ reswitch: } else { - uint32_t addr; + uint64_t tmpu64; - if (i386_record_lea_modrm_addr (&ir, &addr)) + if (i386_record_lea_modrm_addr (&ir, &tmpu64)) return -1; - if (record_arch_list_add_mem (addr, 2)) + if (record_arch_list_add_mem (tmpu64, 2)) return -1; addr += 2; - if (record_arch_list_add_mem (addr, 4)) - return -1; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + if (record_arch_list_add_mem (tmpu64, 8)) + return -1; + } + else + { + if (record_arch_list_add_mem (tmpu64, 4)) + return -1; + } } } break; @@ -4923,9 +5005,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -4937,7 +5016,7 @@ reswitch: case 4: if (ir.mod == 3) { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) + if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b)) return -1; } else @@ -4946,9 +5025,32 @@ reswitch: if (i386_record_lea_modrm (&ir)) return -1; } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* lmsw */ case 6: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); + break; + /* invlpg */ + case 7: + if (ir.mod == 3) + { + 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; } break; @@ -4961,21 +5063,21 @@ reswitch: /* arpl */ case 0x63: - ir.ot = ir.dflag ? OT_LONG : OT_WORD; if (i386_record_modrm (&ir)) return -1; - if (ir.mod != 3) - { - if (i386_record_lea_modrm (&ir)) - return -1; - } + if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM]) + { + I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]? + (ir.reg | rex_r) : ir.rm); + } else - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + { + ir.ot = ir.dflag ? OT_LONG : OT_WORD; + if (i386_record_lea_modrm (&ir)) + return -1; + } + if (!ir.regmap[X86_RECORD_R8_REGNUM]) + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* lar */ @@ -4984,13 +5086,19 @@ reswitch: case 0x0f03: if (i386_record_modrm (&ir)) return -1; - if (record_arch_list_add_reg (ir.regcache, ir.reg)) - return -1; - if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM)) - return -1; + I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r); + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; case 0x0f18: + if (i386_record_modrm (&ir)) + return -1; + if (ir.mod == 3 && ir.reg == 3) + { + ir.addr -= 3; + opcode = opcode << 8 | ir.modrm; + goto no_support; + } break; /* nop (multi byte) */ @@ -5011,7 +5119,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5023,16 +5131,12 @@ reswitch: case 4: case 8: if (opcode & 2) - { - } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); else - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); break; default: - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; break; @@ -5048,22 +5152,19 @@ reswitch: if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4 || ir.reg == 5 || ir.reg >= 8) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } if (opcode & 2) - { - } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); else - { - if (record_arch_list_add_reg (ir.regcache, ir.rm)) - return -1; - } + I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b); break; /* clts */ case 0x0f06: + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM); break; /* MMX/SSE/SSE2/PNI support */ @@ -5078,9 +5179,8 @@ reswitch: break; } -/* In the future, Maybe still need to deal with need_dasm */ - if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM)) - return -1; + /* In the future, Maybe still need to deal with need_dasm */ + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM); if (record_arch_list_add_end ()) return -1; @@ -5093,6 +5193,15 @@ no_support: return -1; } +static const int i386_record_regmap[] = +{ + I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM, + I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM, + 0, 0, 0, 0, 0, 0, 0, 0, + I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM, + I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM +}; + static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -5153,6 +5262,8 @@ i386_gdbarch_init (struct gdbarch_info i tdep->sc_pc_offset = -1; tdep->sc_sp_offset = -1; + tdep->record_regmap = i386_record_regmap; + /* The format used for `long double' on almost all i386 targets is the i387 extended floating-point format. In fact, of all targets in the GCC 2.95 tree, only OSF/1 does it different, and insists --- a/i386-tdep.h +++ b/i386-tdep.h @@ -108,6 +108,9 @@ struct gdbarch_tdep struct type *i386_sse_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order in GDB is not + same with I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ @@ -148,6 +151,36 @@ enum i386_regnum I386_ST0_REGNUM /* %st(0) */ }; +/* Register numbers of RECORD_REGMAP. */ + +enum record_i386_regnum +{ + X86_RECORD_REAX_REGNUM, + X86_RECORD_RECX_REGNUM, + X86_RECORD_REDX_REGNUM, + X86_RECORD_REBX_REGNUM, + X86_RECORD_RESP_REGNUM, + X86_RECORD_REBP_REGNUM, + X86_RECORD_RESI_REGNUM, + X86_RECORD_REDI_REGNUM, + X86_RECORD_R8_REGNUM, + X86_RECORD_R9_REGNUM, + X86_RECORD_R10_REGNUM, + X86_RECORD_R11_REGNUM, + X86_RECORD_R12_REGNUM, + X86_RECORD_R13_REGNUM, + X86_RECORD_R14_REGNUM, + X86_RECORD_R15_REGNUM, + X86_RECORD_REIP_REGNUM, + X86_RECORD_EFLAGS_REGNUM, + X86_RECORD_CS_REGNUM, + X86_RECORD_SS_REGNUM, + X86_RECORD_DS_REGNUM, + X86_RECORD_ES_REGNUM, + X86_RECORD_FS_REGNUM, + X86_RECORD_GS_REGNUM, +}; + #define I386_NUM_GREGS 16 #define I386_NUM_FREGS 16 #define I386_NUM_XREGS 9