* [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3
@ 2009-07-07 2:38 Hui Zhu
2009-07-13 0:52 ` Michael Snyder
0 siblings, 1 reply; 15+ messages in thread
From: Hui Zhu @ 2009-07-07 2:38 UTC (permalink / raw)
To: gdb-patches ml, Michael Snyder
[-- Attachment #1: Type: text/plain, Size: 74491 bytes --]
Because AMD64 instruction set is the extend of I386 instruction set.
So I update the function i386_process_record to make it support AMD64
instruction set. some of other software do something like it.
2009-07-07 Hui Zhu <teawater@gmail.com>
Add AMD64 process record instruction set support.
* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
because the AMD64's registers order in GDB is not same with
I386 instructions.
Add i386_syscall_record to be the syscall function handle
interface.
(record_i386_regnum): Number for record_regmap.
* i386-tdep.c (OT_QUAD): For 64 bits.
(i386_record_s): Add rex_x, rex_b, rip_offset and
popl_esp_hack for AMD64 instruction set. And regmap for
record_regmap.
(i386_record_lea_modrm_addr): Support AMD64 instruction set
64 bits lea.
(i386_record_lea_modrm): Ditto.
(i386_record_push): New function. Record the execution log
of push.
(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
register.
(i386_process_record): Support AMD64 instruction set.
amd64-tdep.c (amd64_record_regmap): For record_regmap.
(amd64_init_abi): Set amd64_record_regmap to record_regmap.
---
amd64-tdep.c | 12
i386-tdep.c | 1444 +++++++++++++++++++++++++++++++----------------------------
i386-tdep.h | 35 +
3 files changed, 830 insertions(+), 661 deletions(-)
--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,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)
{
@@ -2051,6 +2061,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
@@ -2764,6 +2764,7 @@ enum
OT_BYTE = 0,
OT_WORD,
OT_LONG,
+ OT_QUAD,
};
/* i386 arith/logic operations */
@@ -2781,6 +2782,7 @@ enum
struct i386_record_s
{
+ struct gdbarch *gdbarch;
struct regcache *regcache;
CORE_ADDR addr;
int aflag;
@@ -2789,6 +2791,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
@@ -2797,7 +2804,7 @@ struct i386_record_s
static int
i386_record_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
if (target_read_memory (irp->addr, &irp->modrm, 1))
{
@@ -2820,12 +2827,13 @@ 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)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
uint8_t tmpu8;
- uint16_t tmpu16;
- uint32_t tmpu32;
+ int16_t tmpi16;
+ int32_t tmpi32;
+ ULONGEST tmpulongest;
*addr = 0;
if (irp->aflag)
@@ -2849,9 +2857,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)
{
@@ -2859,7 +2868,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 "
@@ -2868,6 +2877,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
{
@@ -2884,10 +2896,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 "
@@ -2895,21 +2907,34 @@ i386_record_lea_modrm_addr (struct i386_
paddress (gdbarch, 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
@@ -2921,7 +2946,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 "
@@ -2930,7 +2955,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;
}
@@ -2949,10 +2974,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 "
@@ -2961,63 +2986,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;
@@ -3034,10 +3071,10 @@ no_rm:
static int
i386_record_lea_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
- uint32_t addr;
+ struct gdbarch *gdbarch = irp->gdbarch;
+ uint64_t addr;
- if (irp->override)
+ if (irp->override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory change "
@@ -3056,10 +3093,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)
@@ -3068,14 +3131,21 @@ 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;
+ ir.gdbarch = gdbarch;
if (record_debug > 1)
fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3106,22 +3176,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;
@@ -3129,16 +3199,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;
@@ -3228,30 +3333,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 */
@@ -3271,17 +3374,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 */
@@ -3302,10 +3405,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 */
@@ -3318,28 +3419,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)
@@ -3349,13 +3439,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:
@@ -3365,15 +3456,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;
@@ -3387,10 +3473,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)
@@ -3399,13 +3481,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))
@@ -3413,42 +3498,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;
@@ -3463,22 +3546,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 */
@@ -3488,12 +3567,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 */
@@ -3505,28 +3587,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 */
@@ -3540,22 +3619,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 */
@@ -3568,14 +3644,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 */
@@ -3589,6 +3662,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 */
@@ -3597,16 +3676,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;
@@ -3619,113 +3718,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 */
@@ -3743,19 +3832,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:
@@ -3763,40 +3854,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;
@@ -3804,38 +3910,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 */
@@ -3848,8 +3924,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 */
@@ -3862,12 +3937,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 */
@@ -3875,62 +3949,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 %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, 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 %s len = 4.\n"),
- paddress (gdbarch, 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 %s len = 4.\n"),
- paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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 */
@@ -3942,8 +4025,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 */
@@ -3955,8 +4039,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 */
@@ -3967,10 +4050,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 */
@@ -3980,33 +4061,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 */
@@ -4024,35 +4107,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 */
@@ -4066,10 +4146,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))
@@ -4077,14 +4155,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:
@@ -4121,9 +4197,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)
{
@@ -4183,16 +4259,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;
}
@@ -4202,16 +4278,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;
}
@@ -4228,43 +4304,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:
@@ -4286,123 +4362,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 %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, 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"),
+ paddress (gdbarch, 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 */
@@ -4410,8 +4451,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:
@@ -4425,48 +4466,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 */
@@ -4528,14 +4553,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))
@@ -4562,34 +4586,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 */
@@ -4600,66 +4623,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 */
@@ -4675,10 +4727,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 */
@@ -4770,16 +4825,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 */
@@ -4790,8 +4847,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 */
@@ -4822,6 +4879,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 "
@@ -4843,16 +4905,37 @@ reswitch:
goto no_support;
break;
+ /* syscall */
+ case 0x0f05:
+ {
+ int ret;
+ if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL)
+ {
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction syscall.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ }
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ if (ret)
+ return ret;
+ }
+ 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 */
@@ -4873,10 +4956,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;
@@ -4893,8 +4973,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;
@@ -4912,7 +4991,7 @@ reswitch:
/* sgdt */
case 0:
{
- uint32_t addr;
+ uint64_t tmpu64;
if (ir.mod == 3)
{
@@ -4920,8 +4999,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 "
@@ -4933,13 +5011,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;
@@ -4953,8 +5039,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;
@@ -4966,7 +5051,7 @@ reswitch:
else
{
/* sidt */
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -4978,15 +5063,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;
@@ -4994,9 +5087,6 @@ reswitch:
case 2:
/* lidt */
case 3:
- /* invlpg */
- case 7:
- default:
if (ir.mod == 3)
{
ir.addr -= 3;
@@ -5008,7 +5098,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
@@ -5017,9 +5107,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;
@@ -5032,21 +5145,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 */
@@ -5055,13 +5168,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) */
@@ -5082,7 +5201,7 @@ reswitch:
return -1;
if ((ir.modrm & 0xc0) != 0xc0)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
@@ -5094,16 +5213,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;
@@ -5119,22 +5234,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 */
@@ -5149,9 +5261,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;
@@ -5164,6 +5275,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
+};
+
\f
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5224,6 +5344,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
@@ -111,10 +111,15 @@ struct gdbarch_tdep
struct type *i387_ext_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. */
int (*i386_sysenter_record) (struct regcache *regcache);
+ /* Parse syscall args. */
+ int (*i386_syscall_record) (struct regcache *regcache);
};
/* Floating-point registers. */
@@ -151,6 +156,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
[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 70867 bytes --]
---
amd64-tdep.c | 12
i386-tdep.c | 1444 +++++++++++++++++++++++++++++++----------------------------
i386-tdep.h | 35 +
3 files changed, 830 insertions(+), 661 deletions(-)
--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,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)
{
@@ -2051,6 +2061,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
@@ -2764,6 +2764,7 @@ enum
OT_BYTE = 0,
OT_WORD,
OT_LONG,
+ OT_QUAD,
};
/* i386 arith/logic operations */
@@ -2781,6 +2782,7 @@ enum
struct i386_record_s
{
+ struct gdbarch *gdbarch;
struct regcache *regcache;
CORE_ADDR addr;
int aflag;
@@ -2789,6 +2791,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
@@ -2797,7 +2804,7 @@ struct i386_record_s
static int
i386_record_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
if (target_read_memory (irp->addr, &irp->modrm, 1))
{
@@ -2820,12 +2827,13 @@ 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)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
uint8_t tmpu8;
- uint16_t tmpu16;
- uint32_t tmpu32;
+ int16_t tmpi16;
+ int32_t tmpi32;
+ ULONGEST tmpulongest;
*addr = 0;
if (irp->aflag)
@@ -2849,9 +2857,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)
{
@@ -2859,7 +2868,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 "
@@ -2868,6 +2877,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
{
@@ -2884,10 +2896,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 "
@@ -2895,21 +2907,34 @@ i386_record_lea_modrm_addr (struct i386_
paddress (gdbarch, 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
@@ -2921,7 +2946,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 "
@@ -2930,7 +2955,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;
}
@@ -2949,10 +2974,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 "
@@ -2961,63 +2986,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;
@@ -3034,10 +3071,10 @@ no_rm:
static int
i386_record_lea_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
- uint32_t addr;
+ struct gdbarch *gdbarch = irp->gdbarch;
+ uint64_t addr;
- if (irp->override)
+ if (irp->override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory change "
@@ -3056,10 +3093,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)
@@ -3068,14 +3131,21 @@ 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;
+ ir.gdbarch = gdbarch;
if (record_debug > 1)
fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3106,22 +3176,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;
@@ -3129,16 +3199,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;
@@ -3228,30 +3333,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 */
@@ -3271,17 +3374,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 */
@@ -3302,10 +3405,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 */
@@ -3318,28 +3419,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)
@@ -3349,13 +3439,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:
@@ -3365,15 +3456,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;
@@ -3387,10 +3473,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)
@@ -3399,13 +3481,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))
@@ -3413,42 +3498,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;
@@ -3463,22 +3546,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 */
@@ -3488,12 +3567,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 */
@@ -3505,28 +3587,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 */
@@ -3540,22 +3619,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 */
@@ -3568,14 +3644,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 */
@@ -3589,6 +3662,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 */
@@ -3597,16 +3676,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;
@@ -3619,113 +3718,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 */
@@ -3743,19 +3832,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:
@@ -3763,40 +3854,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;
@@ -3804,38 +3910,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 */
@@ -3848,8 +3924,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 */
@@ -3862,12 +3937,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 */
@@ -3875,62 +3949,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 %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, 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 %s len = 4.\n"),
- paddress (gdbarch, 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 %s len = 4.\n"),
- paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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"),
+ paddress (gdbarch, 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 */
@@ -3942,8 +4025,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 */
@@ -3955,8 +4039,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 */
@@ -3967,10 +4050,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 */
@@ -3980,33 +4061,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 */
@@ -4024,35 +4107,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 */
@@ -4066,10 +4146,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))
@@ -4077,14 +4155,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:
@@ -4121,9 +4197,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)
{
@@ -4183,16 +4259,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;
}
@@ -4202,16 +4278,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;
}
@@ -4228,43 +4304,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:
@@ -4286,123 +4362,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 %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, 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"),
+ paddress (gdbarch, 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 */
@@ -4410,8 +4451,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:
@@ -4425,48 +4466,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 */
@@ -4528,14 +4553,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))
@@ -4562,34 +4586,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 */
@@ -4600,66 +4623,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 */
@@ -4675,10 +4727,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 */
@@ -4770,16 +4825,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 */
@@ -4790,8 +4847,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 */
@@ -4822,6 +4879,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 "
@@ -4843,16 +4905,37 @@ reswitch:
goto no_support;
break;
+ /* syscall */
+ case 0x0f05:
+ {
+ int ret;
+ if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL)
+ {
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction syscall.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ }
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ if (ret)
+ return ret;
+ }
+ 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 */
@@ -4873,10 +4956,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;
@@ -4893,8 +4973,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;
@@ -4912,7 +4991,7 @@ reswitch:
/* sgdt */
case 0:
{
- uint32_t addr;
+ uint64_t tmpu64;
if (ir.mod == 3)
{
@@ -4920,8 +4999,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 "
@@ -4933,13 +5011,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;
@@ -4953,8 +5039,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;
@@ -4966,7 +5051,7 @@ reswitch:
else
{
/* sidt */
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -4978,15 +5063,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;
@@ -4994,9 +5087,6 @@ reswitch:
case 2:
/* lidt */
case 3:
- /* invlpg */
- case 7:
- default:
if (ir.mod == 3)
{
ir.addr -= 3;
@@ -5008,7 +5098,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
@@ -5017,9 +5107,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;
@@ -5032,21 +5145,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 */
@@ -5055,13 +5168,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) */
@@ -5082,7 +5201,7 @@ reswitch:
return -1;
if ((ir.modrm & 0xc0) != 0xc0)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
@@ -5094,16 +5213,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;
@@ -5119,22 +5234,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 */
@@ -5149,9 +5261,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;
@@ -5164,6 +5275,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
+};
+
\f
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5224,6 +5344,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
@@ -111,10 +111,15 @@ struct gdbarch_tdep
struct type *i387_ext_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. */
int (*i386_sysenter_record) (struct regcache *regcache);
+ /* Parse syscall args. */
+ int (*i386_syscall_record) (struct regcache *regcache);
};
/* Floating-point registers. */
@@ -151,6 +156,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
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-07 2:38 [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 Hui Zhu @ 2009-07-13 0:52 ` Michael Snyder 2009-07-17 8:50 ` Hui Zhu 0 siblings, 1 reply; 15+ messages in thread From: Michael Snyder @ 2009-07-13 0:52 UTC (permalink / raw) To: Hui Zhu; +Cc: gdb-patches ml Hui Zhu wrote: > Because AMD64 instruction set is the extend of I386 instruction set. > So I update the function i386_process_record to make it support AMD64 > instruction set. some of other software do something like it. > 2009-07-07 Hui Zhu <teawater@gmail.com> > > Add AMD64 process record instruction set support. > > * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers > because the AMD64's registers order in GDB is not same with > I386 instructions. > Add i386_syscall_record to be the syscall function handle > interface. > (record_i386_regnum): Number for record_regmap. > * i386-tdep.c (OT_QUAD): For 64 bits. > (i386_record_s): Add rex_x, rex_b, rip_offset and > popl_esp_hack for AMD64 instruction set. And regmap for > record_regmap. > (i386_record_lea_modrm_addr): Support AMD64 instruction set > 64 bits lea. > (i386_record_lea_modrm): Ditto. > (i386_record_push): New function. Record the execution log > of push. > (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the > register. > (i386_process_record): Support AMD64 instruction set. > amd64-tdep.c (amd64_record_regmap): For record_regmap. > (amd64_init_abi): Set amd64_record_regmap to record_regmap. OK, this is kind of preliminary -- mostly concerned with whitespace / formatting. I'll try to do more later. > @@ -2859,7 +2868,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)) Space after a cast, please. There are many instances of this, I won't try to note them all. > @@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_ > return -1; > } > irp->addr++; > - *addr = (int8_t) tmpu8; > + *addr = (int8_t)tmpu8; Space after cast > @@ -2949,10 +2974,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)) No space after '&' operator. In general, we use a space both before and after a binary operator (such as 'plus'), but no space after a unary operator such as '&', '*' or '-'. > + if (ir.aflag == 2) > + { > + if (target_read_memory > + (ir.addr, (gdb_byte *)&addr, 8)) Please try to avoid doing this (putting the left-paren of a function call on the next line). Occasionally when a line gets really long I tend to overlook it, but in this case it would be really easy to divide the line up like this: if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8)) > + if (ir.mod ==3) Space after == > + switch (ir.dflag) > + { > + case 0: > + tmpu64 += ((int16_t)tmpulongest >> 4)<< 4; Space before <<, space after cast. > + break; > + case 1: > + tmpu64 += ((int32_t)tmpulongest >> 5)<< 5; Ditto > + break; > + case 2: > + tmpu64 += ((int64_t)tmpulongest >> 6)<< 6; Ditto > + /* The map for registers because the AMD64's registers order in GDB is not > + same with I386 instructions. */ "same as". And could you shorten the first line please? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-13 0:52 ` Michael Snyder @ 2009-07-17 8:50 ` Hui Zhu 2009-07-18 1:20 ` Michael Snyder 0 siblings, 1 reply; 15+ messages in thread From: Hui Zhu @ 2009-07-17 8:50 UTC (permalink / raw) To: Michael Snyder; +Cc: gdb-patches ml [-- Attachment #1: Type: text/plain, Size: 78309 bytes --] On Mon, Jul 13, 2009 at 08:34, Michael Snyder<msnyder@vmware.com> wrote: > Hui Zhu wrote: >> >> Because AMD64 instruction set is the extend of I386 instruction set. >> So I update the function i386_process_record to make it support AMD64 >> instruction set. some of other software do something like it. >> 2009-07-07 Hui Zhu <teawater@gmail.com> >> >> Add AMD64 process record instruction set support. >> >> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >> because the AMD64's registers order in GDB is not same with >> I386 instructions. >> Add i386_syscall_record to be the syscall function handle >> interface. >> (record_i386_regnum): Number for record_regmap. >> * i386-tdep.c (OT_QUAD): For 64 bits. >> (i386_record_s): Add rex_x, rex_b, rip_offset and >> popl_esp_hack for AMD64 instruction set. And regmap for >> record_regmap. >> (i386_record_lea_modrm_addr): Support AMD64 instruction set >> 64 bits lea. >> (i386_record_lea_modrm): Ditto. >> (i386_record_push): New function. Record the execution log >> of push. >> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >> register. >> (i386_process_record): Support AMD64 instruction set. >> amd64-tdep.c (amd64_record_regmap): For record_regmap. >> (amd64_init_abi): Set amd64_record_regmap to record_regmap. > > OK, this is kind of preliminary -- mostly concerned with > whitespace / formatting. I'll try to do more later. > > >> @@ -2859,7 +2868,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)) > > Space after a cast, please. There are many instances of this, > I won't try to note them all. > >> @@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_ >> return -1; >> } >> irp->addr++; >> - *addr = (int8_t) tmpu8; >> + *addr = (int8_t)tmpu8; > > Space after cast > >> @@ -2949,10 +2974,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)) > > No space after '&' operator. In general, we use a space > both before and after a binary operator (such as 'plus'), > but no space after a unary operator such as '&', '*' or '-'. > >> + if (ir.aflag == 2) >> + { >> + if (target_read_memory >> + (ir.addr, (gdb_byte *)&addr, 8)) > > Please try to avoid doing this (putting the left-paren of a > function call on the next line). Occasionally when a line gets > really long I tend to overlook it, but in this case it would > be really easy to divide the line up like this: > > if (target_read_memory (ir.addr, > (gdb_byte *) &addr, 8)) > >> + if (ir.mod ==3) > > Space after == > >> + switch (ir.dflag) >> + { >> + case 0: >> + tmpu64 += ((int16_t)tmpulongest >> 4)<< 4; > > Space before <<, space after cast. > >> + break; >> + case 1: >> + tmpu64 += ((int32_t)tmpulongest >> 5)<< 5; > > Ditto > >> + break; >> + case 2: >> + tmpu64 += ((int64_t)tmpulongest >> 6)<< 6; > > Ditto > >> + /* The map for registers because the AMD64's registers order in GDB is >> not >> + same with I386 instructions. */ > > "same as". And could you shorten the first line please? > > > Thanks Michael, I updated all the AMD64 patches. Please help me review it. Thanks, Hui 2009-07-17 Hui Zhu <teawater@gmail.com> Add AMD64 process record instruction set support. * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers because the AMD64's registers order in GDB is not same with I386 instructions. Add i386_syscall_record to be the syscall function handle interface. (record_i386_regnum): Number for record_regmap. * i386-tdep.c (OT_QUAD): For 64 bits. (i386_record_s): Add rex_x, rex_b, rip_offset and popl_esp_hack for AMD64 instruction set. And regmap for record_regmap. (i386_record_lea_modrm_addr): Support AMD64 instruction set 64 bits lea. (i386_record_lea_modrm): Ditto. (i386_record_push): New function. Record the execution log of push. (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the register. (i386_process_record): Support AMD64 instruction set. amd64-tdep.c (amd64_record_regmap): For record_regmap. (amd64_init_abi): Set amd64_record_regmap to record_regmap. --- amd64-tdep.c | 12 i386-tdep.c | 1437 +++++++++++++++++++++++++++++++---------------------------- i386-tdep.h | 35 + 3 files changed, 825 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,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) @@ -3151,14 +3214,21 @@ 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; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3259,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; @@ -3212,16 +3282,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; @@ -3311,30 +3416,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 */ @@ -3354,17 +3457,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 */ @@ -3385,10 +3488,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 */ @@ -3401,28 +3502,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) @@ -3432,13 +3522,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: @@ -3448,15 +3539,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; @@ -3470,10 +3556,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) @@ -3482,13 +3564,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)) @@ -3496,42 +3581,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; @@ -3546,22 +3629,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 */ @@ -3571,12 +3650,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 */ @@ -3588,28 +3670,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 */ @@ -3623,22 +3702,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 */ @@ -3651,14 +3727,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 */ @@ -3672,6 +3745,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 */ @@ -3680,16 +3759,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; @@ -3702,113 +3801,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 */ @@ -3826,19 +3915,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: @@ -3846,40 +3937,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; @@ -3887,38 +3993,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 */ @@ -3931,8 +4007,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 */ @@ -3945,12 +4020,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 */ @@ -3958,62 +4032,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4105,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 */ @@ -4038,8 +4119,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 */ @@ -4050,10 +4130,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 */ @@ -4063,33 +4141,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 */ @@ -4107,35 +4187,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 */ @@ -4149,10 +4226,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)) @@ -4160,14 +4235,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: @@ -4204,9 +4277,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) { @@ -4266,16 +4339,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; } @@ -4285,16 +4358,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; } @@ -4311,43 +4384,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: @@ -4369,123 +4442,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4531,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: @@ -4508,48 +4546,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 */ @@ -4611,14 +4633,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)) @@ -4645,34 +4666,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 */ @@ -4683,66 +4703,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 */ @@ -4758,10 +4807,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 */ @@ -4853,16 +4905,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 */ @@ -4873,8 +4927,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 */ @@ -4905,6 +4959,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 " @@ -4926,16 +4985,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5036,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; @@ -4976,8 +5053,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; @@ -4995,7 +5071,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5079,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 " @@ -5016,13 +5091,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; @@ -5036,8 +5119,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; @@ -5049,7 +5131,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5143,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; @@ -5077,9 +5167,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5178,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 @@ -5100,9 +5187,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; @@ -5115,21 +5225,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 */ @@ -5138,13 +5248,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) */ @@ -5165,7 +5281,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5293,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; @@ -5202,22 +5314,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 */ @@ -5232,9 +5341,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; @@ -5247,6 +5355,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) @@ -5307,6 +5424,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 [-- Attachment #2: prec_amd64_tdep.txt --] [-- Type: text/plain, Size: 70749 bytes --] --- amd64-tdep.c | 12 i386-tdep.c | 1437 +++++++++++++++++++++++++++++++---------------------------- i386-tdep.h | 35 + 3 files changed, 825 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,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) @@ -3151,14 +3214,21 @@ 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; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3259,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; @@ -3212,16 +3282,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; @@ -3311,30 +3416,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 */ @@ -3354,17 +3457,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 */ @@ -3385,10 +3488,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 */ @@ -3401,28 +3502,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) @@ -3432,13 +3522,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: @@ -3448,15 +3539,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; @@ -3470,10 +3556,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) @@ -3482,13 +3564,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)) @@ -3496,42 +3581,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; @@ -3546,22 +3629,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 */ @@ -3571,12 +3650,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 */ @@ -3588,28 +3670,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 */ @@ -3623,22 +3702,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 */ @@ -3651,14 +3727,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 */ @@ -3672,6 +3745,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 */ @@ -3680,16 +3759,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; @@ -3702,113 +3801,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 */ @@ -3826,19 +3915,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: @@ -3846,40 +3937,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; @@ -3887,38 +3993,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 */ @@ -3931,8 +4007,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 */ @@ -3945,12 +4020,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 */ @@ -3958,62 +4032,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4105,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 */ @@ -4038,8 +4119,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 */ @@ -4050,10 +4130,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 */ @@ -4063,33 +4141,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 */ @@ -4107,35 +4187,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 */ @@ -4149,10 +4226,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)) @@ -4160,14 +4235,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: @@ -4204,9 +4277,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) { @@ -4266,16 +4339,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; } @@ -4285,16 +4358,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; } @@ -4311,43 +4384,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: @@ -4369,123 +4442,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4531,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: @@ -4508,48 +4546,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 */ @@ -4611,14 +4633,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)) @@ -4645,34 +4666,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 */ @@ -4683,66 +4703,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 */ @@ -4758,10 +4807,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 */ @@ -4853,16 +4905,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 */ @@ -4873,8 +4927,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 */ @@ -4905,6 +4959,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 " @@ -4926,16 +4985,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5036,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; @@ -4976,8 +5053,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; @@ -4995,7 +5071,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5079,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 " @@ -5016,13 +5091,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; @@ -5036,8 +5119,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; @@ -5049,7 +5131,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5143,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; @@ -5077,9 +5167,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5178,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 @@ -5100,9 +5187,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; @@ -5115,21 +5225,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 */ @@ -5138,13 +5248,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) */ @@ -5165,7 +5281,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5293,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; @@ -5202,22 +5314,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 */ @@ -5232,9 +5341,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; @@ -5247,6 +5355,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 +}; + \f static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -5307,6 +5424,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-17 8:50 ` Hui Zhu @ 2009-07-18 1:20 ` Michael Snyder 2009-07-19 17:21 ` Hui Zhu 0 siblings, 1 reply; 15+ messages in thread From: Michael Snyder @ 2009-07-18 1:20 UTC (permalink / raw) To: Hui Zhu; +Cc: gdb-patches ml, mark.kettenis > Thanks Michael, > > I updated all the AMD64 patches. Please help me review it. > > Thanks, > Hui > > 2009-07-17 Hui Zhu <teawater@gmail.com> > > Add AMD64 process record instruction set support. > > * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers > because the AMD64's registers order in GDB is not same with > I386 instructions. > Add i386_syscall_record to be the syscall function handle > interface. > (record_i386_regnum): Number for record_regmap. > * i386-tdep.c (OT_QUAD): For 64 bits. > (i386_record_s): Add rex_x, rex_b, rip_offset and > popl_esp_hack for AMD64 instruction set. And regmap for > record_regmap. > (i386_record_lea_modrm_addr): Support AMD64 instruction set > 64 bits lea. > (i386_record_lea_modrm): Ditto. > (i386_record_push): New function. Record the execution log > of push. > (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the > register. > (i386_process_record): Support AMD64 instruction set. > amd64-tdep.c (amd64_record_regmap): For record_regmap. Should be a "*" at the beginning of the line above. > @@ -2864,6 +2865,7 @@ enum > > struct i386_record_s > { > + struct gdbarch *gdbarch; > struct regcache *regcache; > CORE_ADDR addr; > int aflag; > @@ -2872,6 +2874,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; popl_esp_hack is used but never initialized. Do you still need it? Is it for some future use? > @@ -4611,14 +4633,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)); Space before colon operator (':'), and then the 2nd line isn't indented right. I know it looks prettier the way it is, but it should be over to the left. ;-) > @@ -5115,21 +5225,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); Space before question-mark, and then the indentation of the second line. > @@ -5232,9 +5341,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 */ "maybe" lower case. Period and two spaces at end of sentence. Everything else in this patch looks great! Mark Kettenis should approve it, though. Michael ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-18 1:20 ` Michael Snyder @ 2009-07-19 17:21 ` Hui Zhu 2009-07-19 21:22 ` Mark Kettenis ` (3 more replies) 0 siblings, 4 replies; 15+ messages in thread From: Hui Zhu @ 2009-07-19 17:21 UTC (permalink / raw) To: Michael Snyder, Mark Kettenis; +Cc: gdb-patches ml [-- Attachment #1: Type: text/plain, Size: 78123 bytes --] On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: > >> Thanks Michael, >> >> I updated all the AMD64 patches. Please help me review it. >> >> Thanks, >> Hui >> >> 2009-07-17 Hui Zhu <teawater@gmail.com> >> >> Add AMD64 process record instruction set support. >> >> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >> because the AMD64's registers order in GDB is not same with >> I386 instructions. >> Add i386_syscall_record to be the syscall function handle >> interface. >> (record_i386_regnum): Number for record_regmap. >> * i386-tdep.c (OT_QUAD): For 64 bits. >> (i386_record_s): Add rex_x, rex_b, rip_offset and >> popl_esp_hack for AMD64 instruction set. And regmap for >> record_regmap. >> (i386_record_lea_modrm_addr): Support AMD64 instruction set >> 64 bits lea. >> (i386_record_lea_modrm): Ditto. >> (i386_record_push): New function. Record the execution log >> of push. >> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >> register. >> (i386_process_record): Support AMD64 instruction set. >> amd64-tdep.c (amd64_record_regmap): For record_regmap. > > Should be a "*" at the beginning of the line above. > > >> @@ -2864,6 +2865,7 @@ enum >> >> struct i386_record_s >> { >> + struct gdbarch *gdbarch; >> struct regcache *regcache; >> CORE_ADDR addr; >> int aflag; >> @@ -2872,6 +2874,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; > > popl_esp_hack is used but never initialized. > Do you still need it? Is it for some future use? > > >> @@ -4611,14 +4633,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)); > > Space before colon operator (':'), and then > the 2nd line isn't indented right. I know it > looks prettier the way it is, but it should be > over to the left. ;-) > > >> @@ -5115,21 +5225,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); > > Space before question-mark, and then the indentation of the second line. > > >> @@ -5232,9 +5341,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 */ > > "maybe" lower case. Period and two spaces at end of sentence. > > > Everything else in this patch looks great! > > Mark Kettenis should approve it, though. > Thanks Michael. I update the patches according to your mail except changelog. Because It sames that we just add * at the begin of the function name. Please help me review it. Thanks, Hui 2009-07-20 Hui Zhu <teawater@gmail.com> Add AMD64 process record instruction set support. * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers because the AMD64's registers order in GDB is not same with I386 instructions. Add i386_syscall_record to be the syscall function handle interface. (record_i386_regnum): Number for record_regmap. * i386-tdep.c (OT_QUAD): For 64 bits. (i386_record_s): Add rex_x, rex_b, rip_offset and popl_esp_hack for AMD64 instruction set. And regmap for record_regmap. (i386_record_lea_modrm_addr): Support AMD64 instruction set 64 bits lea. (i386_record_lea_modrm): Ditto. (i386_record_push): New function. Record the execution log of push. (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the register. (i386_process_record): Support AMD64 instruction set. amd64-tdep.c (amd64_record_regmap): For record_regmap. (amd64_init_abi): Set amd64_record_regmap to record_regmap. --- amd64-tdep.c | 12 i386-tdep.c | 1439 +++++++++++++++++++++++++++++++---------------------------- i386-tdep.h | 35 + 3 files changed, 827 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,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) @@ -3151,14 +3214,22 @@ 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.popl_esp_hack = 0; + ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3260,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; @@ -3212,16 +3283,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; @@ -3311,30 +3417,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 */ @@ -3354,17 +3458,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 */ @@ -3385,10 +3489,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 */ @@ -3401,28 +3503,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) @@ -3432,13 +3523,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: @@ -3448,15 +3540,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; @@ -3470,10 +3557,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) @@ -3482,13 +3565,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)) @@ -3496,42 +3582,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; @@ -3546,22 +3630,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 */ @@ -3571,12 +3651,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 */ @@ -3588,28 +3671,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 */ @@ -3623,22 +3703,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 */ @@ -3651,14 +3728,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 */ @@ -3672,6 +3746,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 */ @@ -3680,16 +3760,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; @@ -3702,113 +3802,104 @@ 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 { + ir.popl_esp_hack = 1 << ir.ot; 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 */ @@ -3826,19 +3917,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: @@ -3846,40 +3939,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; @@ -3887,38 +3995,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 */ @@ -3931,8 +4009,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 */ @@ -3945,12 +4022,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 */ @@ -3958,62 +4034,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4107,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 */ @@ -4038,8 +4121,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 */ @@ -4050,10 +4132,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 */ @@ -4063,33 +4143,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 */ @@ -4107,35 +4189,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 */ @@ -4149,10 +4228,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)) @@ -4160,14 +4237,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: @@ -4204,9 +4279,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) { @@ -4266,16 +4341,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; } @@ -4285,16 +4360,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; } @@ -4311,43 +4386,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: @@ -4369,123 +4444,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4533,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: @@ -4508,48 +4548,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 */ @@ -4611,14 +4635,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)) @@ -4645,34 +4668,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 */ @@ -4683,66 +4705,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 */ @@ -4758,10 +4809,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 */ @@ -4853,16 +4907,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 */ @@ -4873,8 +4929,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 */ @@ -4905,6 +4961,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 " @@ -4926,16 +4987,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5038,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; @@ -4976,8 +5055,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; @@ -4995,7 +5073,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5081,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 " @@ -5016,13 +5093,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; @@ -5036,8 +5121,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; @@ -5049,7 +5133,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5145,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; @@ -5077,9 +5169,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5180,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 @@ -5100,9 +5189,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; @@ -5115,21 +5227,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 */ @@ -5138,13 +5250,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) */ @@ -5165,7 +5283,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5295,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; @@ -5202,22 +5316,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 */ @@ -5232,9 +5343,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; @@ -5247,6 +5357,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) @@ -5307,6 +5426,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 [-- Attachment #2: prec_amd64_tdep.txt --] [-- Type: text/plain, Size: 70831 bytes --] --- amd64-tdep.c | 12 i386-tdep.c | 1439 +++++++++++++++++++++++++++++++---------------------------- i386-tdep.h | 35 + 3 files changed, 827 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,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) @@ -3151,14 +3214,22 @@ 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.popl_esp_hack = 0; + ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3260,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; @@ -3212,16 +3283,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; @@ -3311,30 +3417,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 */ @@ -3354,17 +3458,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 */ @@ -3385,10 +3489,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 */ @@ -3401,28 +3503,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) @@ -3432,13 +3523,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: @@ -3448,15 +3540,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; @@ -3470,10 +3557,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) @@ -3482,13 +3565,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)) @@ -3496,42 +3582,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; @@ -3546,22 +3630,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 */ @@ -3571,12 +3651,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 */ @@ -3588,28 +3671,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 */ @@ -3623,22 +3703,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 */ @@ -3651,14 +3728,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 */ @@ -3672,6 +3746,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 */ @@ -3680,16 +3760,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; @@ -3702,113 +3802,104 @@ 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 { + ir.popl_esp_hack = 1 << ir.ot; 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 */ @@ -3826,19 +3917,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: @@ -3846,40 +3939,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; @@ -3887,38 +3995,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 */ @@ -3931,8 +4009,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 */ @@ -3945,12 +4022,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 */ @@ -3958,62 +4034,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4107,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 */ @@ -4038,8 +4121,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 */ @@ -4050,10 +4132,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 */ @@ -4063,33 +4143,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 */ @@ -4107,35 +4189,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 */ @@ -4149,10 +4228,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)) @@ -4160,14 +4237,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: @@ -4204,9 +4279,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) { @@ -4266,16 +4341,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; } @@ -4285,16 +4360,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; } @@ -4311,43 +4386,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: @@ -4369,123 +4444,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4533,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: @@ -4508,48 +4548,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 */ @@ -4611,14 +4635,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)) @@ -4645,34 +4668,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 */ @@ -4683,66 +4705,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 */ @@ -4758,10 +4809,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 */ @@ -4853,16 +4907,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 */ @@ -4873,8 +4929,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 */ @@ -4905,6 +4961,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 " @@ -4926,16 +4987,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5038,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; @@ -4976,8 +5055,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; @@ -4995,7 +5073,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5081,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 " @@ -5016,13 +5093,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; @@ -5036,8 +5121,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; @@ -5049,7 +5133,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5145,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; @@ -5077,9 +5169,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5180,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 @@ -5100,9 +5189,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; @@ -5115,21 +5227,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 */ @@ -5138,13 +5250,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) */ @@ -5165,7 +5283,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5295,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; @@ -5202,22 +5316,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 */ @@ -5232,9 +5343,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; @@ -5247,6 +5357,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 +}; + \f static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -5307,6 +5426,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-19 17:21 ` Hui Zhu @ 2009-07-19 21:22 ` Mark Kettenis 2009-07-20 6:14 ` Hui Zhu 2009-07-20 1:39 ` Michael Snyder ` (2 subsequent siblings) 3 siblings, 1 reply; 15+ messages in thread From: Mark Kettenis @ 2009-07-19 21:22 UTC (permalink / raw) To: teawater; +Cc: msnyder, gdb-patches > From: Hui Zhu <teawater@gmail.com> > Date: Mon, 20 Jul 2009 01:16:10 +0800 > /* 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) > + Hmm, I really disklike this macro. Having that return embedded in there is really bad. The current implementation of record_arch_list_add_reg() always returns 0, so I don't see why you need it. You should make record_arch_list_add_reg(). ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-19 21:22 ` Mark Kettenis @ 2009-07-20 6:14 ` Hui Zhu 0 siblings, 0 replies; 15+ messages in thread From: Hui Zhu @ 2009-07-20 6:14 UTC (permalink / raw) To: Mark Kettenis; +Cc: msnyder, gdb-patches On Mon, Jul 20, 2009 at 01:39, Mark Kettenis<mark.kettenis@xs4all.nl> wrote: >> From: Hui Zhu <teawater@gmail.com> >> Date: Mon, 20 Jul 2009 01:16:10 +0800 > >> /* 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) >> + > > Hmm, I really disklike this macro. Having that return embedded in > there is really bad. > > The current implementation of record_arch_list_add_reg() always > returns 0, so I don't see why you need it. > > You should make record_arch_list_add_reg(). > Thanks Mark, I will change it to: +#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \ + record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)]) + And about the the "record_arch_list_add_reg", I will post a special patch to change it to void later. Thanks, Hui ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-19 17:21 ` Hui Zhu 2009-07-19 21:22 ` Mark Kettenis @ 2009-07-20 1:39 ` Michael Snyder 2009-07-20 10:22 ` Hui Zhu 2009-07-25 22:07 ` Michael Snyder 2009-07-25 22:20 ` Michael Snyder 3 siblings, 1 reply; 15+ messages in thread From: Michael Snyder @ 2009-07-20 1:39 UTC (permalink / raw) To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml Hi Hui, I think I discovered a bug in this one. In 64-bit mode, the "call immediate" instruction is not correctly logging the pushed return address. It's only saving 4 bytes. Please tell me what you think of this patch to your patch? Michael --- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700 +++ tmp/i386-tdep.c 2009-07-19 17:51:51.000907000 -0700 @@ -4563,6 +4563,8 @@ reswitch: /* call im */ case 0xe8: + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; if (i386_record_push (&ir, 1 << (ir.dflag + 1))) return -1; break; ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-20 1:39 ` Michael Snyder @ 2009-07-20 10:22 ` Hui Zhu 2009-07-20 14:24 ` Hui Zhu 0 siblings, 1 reply; 15+ messages in thread From: Hui Zhu @ 2009-07-20 10:22 UTC (permalink / raw) To: Michael Snyder; +Cc: Mark Kettenis, gdb-patches ml Oops, I found a lot of push code need be check clear. Thanks for you remind me. I will check them all. Hui On Mon, Jul 20, 2009 at 08:51, Michael Snyder<msnyder@vmware.com> wrote: > Hi Hui, > > I think I discovered a bug in this one. In 64-bit mode, > the "call immediate" instruction is not correctly logging > the pushed return address. It's only saving 4 bytes. > > Please tell me what you think of this patch to your patch? > > Michael > > --- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700 > +++ tmp/i386-tdep.c 2009-07-19 17:51:51.000907000 -0700 > @@ -4563,6 +4563,8 @@ reswitch: > > /* call im */ > case 0xe8: > + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) > + ir.dflag = 2; > if (i386_record_push (&ir, 1 << (ir.dflag + 1))) > return -1; > break; > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-20 10:22 ` Hui Zhu @ 2009-07-20 14:24 ` Hui Zhu 0 siblings, 0 replies; 15+ messages in thread From: Hui Zhu @ 2009-07-20 14:24 UTC (permalink / raw) To: Michael Snyder, Mark Kettenis; +Cc: gdb-patches ml [-- Attachment #1: Type: text/plain, Size: 75557 bytes --] On Mon, Jul 20, 2009 at 14:13, Hui Zhu<teawater@gmail.com> wrote: > Oops, I found a lot of push code need be check clear. > > Thanks for you remind me. I will check them all. > > Hui > > On Mon, Jul 20, 2009 at 08:51, Michael Snyder<msnyder@vmware.com> wrote: >> Hi Hui, >> >> I think I discovered a bug in this one. In 64-bit mode, >> the "call immediate" instruction is not correctly logging >> the pushed return address. It's only saving 4 bytes. >> >> Please tell me what you think of this patch to your patch? >> >> Michael >> >> --- i386-tdep.c 2009-07-19 17:51:58.000300000 -0700 >> +++ tmp/i386-tdep.c 2009-07-19 17:51:51.000907000 -0700 >> @@ -4563,6 +4563,8 @@ reswitch: >> >> /* call im */ >> case 0xe8: >> + if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) >> + ir.dflag = 2; >> if (i386_record_push (&ir, 1 << (ir.dflag + 1))) >> return -1; >> break; >> >> > Hi guys, I make a new version to fix the error. Please help me review it. Thanks, Hui 2009-07-20 Hui Zhu <teawater@gmail.com> Michael Snyder <msnyder@vmware.com> Add AMD64 process record instruction set support. * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers because the AMD64's registers order in GDB is not same with I386 instructions. Add i386_syscall_record to be the syscall function handle interface. (record_i386_regnum): Number for record_regmap. * i386-tdep.c (OT_QUAD): For 64 bits. (i386_record_s): Add rex_x, rex_b, rip_offset and popl_esp_hack for AMD64 instruction set. And regmap for record_regmap. (i386_record_lea_modrm_addr): Support AMD64 instruction set 64 bits lea. (i386_record_lea_modrm): Ditto. (i386_record_push): New function. Record the execution log of push. (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the register. (i386_process_record): Support AMD64 instruction set. amd64-tdep.c (amd64_record_regmap): For record_regmap. (amd64_init_abi): Set amd64_record_regmap to record_regmap. --- amd64-tdep.c | 12 i386-tdep.c | 1445 ++++++++++++++++++++++++++++++++--------------------------- i386-tdep.h | 35 + 3 files changed, 833 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,33 @@ 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) \ + record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)]) + int i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr) @@ -3151,14 +3211,22 @@ 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.popl_esp_hack = 0; + ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3257,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; @@ -3212,16 +3280,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; @@ -3311,30 +3414,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 */ @@ -3354,17 +3455,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 */ @@ -3385,10 +3486,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 */ @@ -3401,28 +3500,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) @@ -3432,13 +3520,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: @@ -3448,15 +3537,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; @@ -3470,10 +3554,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) @@ -3482,13 +3562,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)) @@ -3496,42 +3579,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 + 1))) 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; @@ -3546,22 +3627,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 */ @@ -3571,12 +3648,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 */ @@ -3588,28 +3668,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 */ @@ -3623,22 +3700,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 */ @@ -3651,14 +3725,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 */ @@ -3672,6 +3743,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 */ @@ -3680,16 +3757,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; @@ -3702,113 +3799,104 @@ 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 { + ir.popl_esp_hack = 1 << ir.ot; 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 */ @@ -3826,19 +3914,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: @@ -3846,40 +3936,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; @@ -3887,38 +3992,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 */ @@ -3931,8 +4006,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 */ @@ -3945,12 +4019,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 */ @@ -3958,62 +4031,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4104,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 */ @@ -4038,8 +4118,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 */ @@ -4050,10 +4129,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 */ @@ -4063,33 +4140,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 */ @@ -4107,35 +4186,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 */ @@ -4149,10 +4225,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)) @@ -4160,14 +4234,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: @@ -4204,9 +4276,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) { @@ -4266,16 +4338,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; } @@ -4285,16 +4357,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; } @@ -4311,43 +4383,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: @@ -4369,123 +4441,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4530,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: @@ -4508,48 +4545,39 @@ 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 (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + 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; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM); + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; /* jmp im */ @@ -4611,14 +4639,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)) @@ -4645,34 +4672,35 @@ 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 (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + 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 */ @@ -4683,66 +4711,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 */ @@ -4758,10 +4815,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 */ @@ -4853,16 +4913,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 */ @@ -4873,8 +4935,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 */ @@ -4905,6 +4967,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 " @@ -4926,16 +4993,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5044,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; @@ -4976,8 +5061,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; @@ -4995,7 +5079,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5087,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 " @@ -5016,13 +5099,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; @@ -5036,8 +5127,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; @@ -5049,7 +5139,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5151,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; @@ -5077,9 +5175,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5186,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 @@ -5100,9 +5195,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; @@ -5115,21 +5233,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 */ @@ -5138,13 +5256,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) */ @@ -5165,7 +5289,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5301,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; @@ -5202,22 +5322,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 */ @@ -5232,9 +5349,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; @@ -5247,6 +5363,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) @@ -5307,6 +5432,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 [-- Attachment #2: prec_amd64_tdep.txt --] [-- Type: text/plain, Size: 71041 bytes --] --- amd64-tdep.c | 12 i386-tdep.c | 1445 ++++++++++++++++++++++++++++++++--------------------------- i386-tdep.h | 35 + 3 files changed, 833 insertions(+), 659 deletions(-) --- a/amd64-tdep.c +++ b/amd64-tdep.c @@ -1989,6 +1989,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) { @@ -2051,6 +2061,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 @@ -2847,6 +2847,7 @@ enum OT_BYTE = 0, OT_WORD, OT_LONG, + OT_QUAD, }; /* i386 arith/logic operations */ @@ -2864,6 +2865,7 @@ enum struct i386_record_s { + struct gdbarch *gdbarch; struct regcache *regcache; CORE_ADDR addr; int aflag; @@ -2872,6 +2874,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 @@ -2880,7 +2887,7 @@ struct i386_record_s static int i386_record_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; if (target_read_memory (irp->addr, &irp->modrm, 1)) { @@ -2903,12 +2910,13 @@ 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) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); + struct gdbarch *gdbarch = irp->gdbarch; uint8_t tmpu8; - uint16_t tmpu16; - uint32_t tmpu32; + int16_t tmpi16; + int32_t tmpi32; + ULONGEST tmpulongest; *addr = 0; if (irp->aflag) @@ -2932,9 +2940,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) { @@ -2942,7 +2951,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 " @@ -2951,6 +2960,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 { @@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_ paddress (gdbarch, 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 @@ -3004,7 +3029,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 " @@ -3013,7 +3038,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; } @@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_ *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 " @@ -3044,63 +3069,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; @@ -3117,10 +3154,10 @@ no_rm: static int i386_record_lea_modrm (struct i386_record_s *irp) { - struct gdbarch *gdbarch = get_regcache_arch (irp->regcache); - uint32_t addr; + struct gdbarch *gdbarch = irp->gdbarch; + uint64_t addr; - if (irp->override) + if (irp->override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory change " @@ -3139,10 +3176,33 @@ 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) \ + record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)]) + int i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr) @@ -3151,14 +3211,22 @@ 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.popl_esp_hack = 0; + ir.regmap = gdbarch_tdep (gdbarch)->record_regmap; + ir.gdbarch = gdbarch; if (record_debug > 1) fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record " @@ -3189,22 +3257,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; @@ -3212,16 +3280,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; @@ -3311,30 +3414,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 */ @@ -3354,17 +3455,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 */ @@ -3385,10 +3486,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 */ @@ -3401,28 +3500,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) @@ -3432,13 +3520,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: @@ -3448,15 +3537,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; @@ -3470,10 +3554,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) @@ -3482,13 +3562,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)) @@ -3496,42 +3579,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 + 1))) 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; @@ -3546,22 +3627,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 */ @@ -3571,12 +3648,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 */ @@ -3588,28 +3668,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 */ @@ -3623,22 +3700,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 */ @@ -3651,14 +3725,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 */ @@ -3672,6 +3743,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 */ @@ -3680,16 +3757,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; @@ -3702,113 +3799,104 @@ 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 { + ir.popl_esp_hack = 1 << ir.ot; 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 */ @@ -3826,19 +3914,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: @@ -3846,40 +3936,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; @@ -3887,38 +3992,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 */ @@ -3931,8 +4006,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 */ @@ -3945,12 +4019,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 */ @@ -3958,62 +4031,68 @@ 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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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 %s len = 4.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4025,8 +4104,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 */ @@ -4038,8 +4118,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 */ @@ -4050,10 +4129,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 */ @@ -4063,33 +4140,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 */ @@ -4107,35 +4186,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 */ @@ -4149,10 +4225,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)) @@ -4160,14 +4234,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: @@ -4204,9 +4276,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) { @@ -4266,16 +4338,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; } @@ -4285,16 +4357,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; } @@ -4311,43 +4383,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: @@ -4369,123 +4441,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 %s because " - "it can't get the value of the segment " - "register.\n"), - paddress (gdbarch, 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"), + paddress (gdbarch, 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 */ @@ -4493,8 +4530,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: @@ -4508,48 +4545,39 @@ 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 (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + 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; + if (ir.regmap[X86_RECORD_R8_REGNUM]) + { + ir.addr -= 1; + goto no_support; + } + I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM); + if (i386_record_push (&ir, 1 << (ir.dflag + 1))) + return -1; break; /* jmp im */ @@ -4611,14 +4639,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)) @@ -4645,34 +4672,35 @@ 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 (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag) + ir.dflag = 2; + 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 */ @@ -4683,66 +4711,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 */ @@ -4758,10 +4815,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 */ @@ -4853,16 +4913,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 */ @@ -4873,8 +4935,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 */ @@ -4905,6 +4967,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 " @@ -4926,16 +4993,37 @@ reswitch: goto no_support; break; + /* syscall */ + case 0x0f05: + { + int ret; + if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL) + { + printf_unfiltered (_("Process record doesn't support " + "instruction syscall.\n")); + ir.addr -= 2; + goto no_support; + } + ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache); + if (ret) + return ret; + } + 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 */ @@ -4956,10 +5044,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; @@ -4976,8 +5061,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; @@ -4995,7 +5079,7 @@ reswitch: /* sgdt */ case 0: { - uint32_t addr; + uint64_t tmpu64; if (ir.mod == 3) { @@ -5003,8 +5087,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 " @@ -5016,13 +5099,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; @@ -5036,8 +5127,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; @@ -5049,7 +5139,7 @@ reswitch: else { /* sidt */ - if (ir.override) + if (ir.override >= 0) { if (record_debug) printf_unfiltered (_("Process record ignores the memory " @@ -5061,15 +5151,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; @@ -5077,9 +5175,6 @@ reswitch: case 2: /* lidt */ case 3: - /* invlpg */ - case 7: - default: if (ir.mod == 3) { ir.addr -= 3; @@ -5091,7 +5186,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 @@ -5100,9 +5195,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; @@ -5115,21 +5233,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 */ @@ -5138,13 +5256,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) */ @@ -5165,7 +5289,7 @@ reswitch: return -1; if ((ir.modrm & 0xc0) != 0xc0) { - ir.addr -= 2; + ir.addr -= 3; opcode = opcode << 8 | ir.modrm; goto no_support; } @@ -5177,16 +5301,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; @@ -5202,22 +5322,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 */ @@ -5232,9 +5349,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; @@ -5247,6 +5363,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 +}; + \f static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) @@ -5307,6 +5432,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 @@ -111,10 +111,15 @@ struct gdbarch_tdep struct type *i387_ext_type; /* Process record/replay target. */ + /* The map for registers because the AMD64's registers order + in GDB is not same as I386 instructions. */ + const int *record_regmap; /* Parse intx80 args. */ int (*i386_intx80_record) (struct regcache *regcache); /* Parse sysenter args. */ int (*i386_sysenter_record) (struct regcache *regcache); + /* Parse syscall args. */ + int (*i386_syscall_record) (struct regcache *regcache); }; /* Floating-point registers. */ @@ -151,6 +156,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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-19 17:21 ` Hui Zhu 2009-07-19 21:22 ` Mark Kettenis 2009-07-20 1:39 ` Michael Snyder @ 2009-07-25 22:07 ` Michael Snyder 2009-07-27 16:50 ` Hui Zhu 2009-07-25 22:20 ` Michael Snyder 3 siblings, 1 reply; 15+ messages in thread From: Michael Snyder @ 2009-07-25 22:07 UTC (permalink / raw) To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml Hui Zhu wrote: > On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: >>> Thanks Michael, >>> >>> I updated all the AMD64 patches. Please help me review it. >>> >>> Thanks, >>> Hui >>> >>> 2009-07-17 Hui Zhu <teawater@gmail.com> >>> >>> Add AMD64 process record instruction set support. >>> >>> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >>> because the AMD64's registers order in GDB is not same with >>> I386 instructions. >>> Add i386_syscall_record to be the syscall function handle >>> interface. >>> (record_i386_regnum): Number for record_regmap. >>> * i386-tdep.c (OT_QUAD): For 64 bits. >>> (i386_record_s): Add rex_x, rex_b, rip_offset and >>> popl_esp_hack for AMD64 instruction set. And regmap for >>> record_regmap. >>> (i386_record_lea_modrm_addr): Support AMD64 instruction set >>> 64 bits lea. >>> (i386_record_lea_modrm): Ditto. >>> (i386_record_push): New function. Record the execution log >>> of push. >>> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >>> register. >>> (i386_process_record): Support AMD64 instruction set. >>> amd64-tdep.c (amd64_record_regmap): For record_regmap. >> Should be a "*" at the beginning of the line above. > Thanks Michael. > > I update the patches according to your mail except changelog. Because > It sames that we just add * at the begin of the function name. No, we add * before a file name. Like this: * amd64-tdep.c (amd64_record_regmap): For record_regmap. (amd64_init_abi): Set amd64_record_regmap to record_regmap. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-25 22:07 ` Michael Snyder @ 2009-07-27 16:50 ` Hui Zhu 0 siblings, 0 replies; 15+ messages in thread From: Hui Zhu @ 2009-07-27 16:50 UTC (permalink / raw) To: Michael Snyder; +Cc: Mark Kettenis, gdb-patches ml On Sun, Jul 26, 2009 at 04:49, Michael Snyder<msnyder@vmware.com> wrote: > Hui Zhu wrote: >> >> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: >>>> >>>> Thanks Michael, >>>> >>>> I updated all the AMD64 patches. Please help me review it. >>>> >>>> Thanks, >>>> Hui >>>> >>>> 2009-07-17 Hui Zhu <teawater@gmail.com> >>>> >>>> Add AMD64 process record instruction set support. >>>> >>>> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >>>> because the AMD64's registers order in GDB is not same with >>>> I386 instructions. >>>> Add i386_syscall_record to be the syscall function handle >>>> interface. >>>> (record_i386_regnum): Number for record_regmap. >>>> * i386-tdep.c (OT_QUAD): For 64 bits. >>>> (i386_record_s): Add rex_x, rex_b, rip_offset and >>>> popl_esp_hack for AMD64 instruction set. And regmap for >>>> record_regmap. >>>> (i386_record_lea_modrm_addr): Support AMD64 instruction set >>>> 64 bits lea. >>>> (i386_record_lea_modrm): Ditto. >>>> (i386_record_push): New function. Record the execution log >>>> of push. >>>> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >>>> register. >>>> (i386_process_record): Support AMD64 instruction set. >>>> amd64-tdep.c (amd64_record_regmap): For record_regmap. >>> >>> Should be a "*" at the beginning of the line above. > >> Thanks Michael. >> >> I update the patches according to your mail except changelog. Because >> It sames that we just add * at the begin of the function name. > > No, we add * before a file name. Like this: > > * amd64-tdep.c (amd64_record_regmap): For record_regmap. > (amd64_init_abi): Set amd64_record_regmap to record_regmap. > > Oops, I forgot the last one. Really sorry for it. 2009-07-20 Hui Zhu <teawater@gmail.com> Add AMD64 process record instruction set support. * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers because the AMD64's registers order in GDB is not same with I386 instructions. Add i386_syscall_record to be the syscall function handle interface. (record_i386_regnum): Number for record_regmap. * i386-tdep.c (OT_QUAD): For 64 bits. (i386_record_s): Add rex_x, rex_b, rip_offset and popl_esp_hack for AMD64 instruction set. And regmap for record_regmap. (i386_record_lea_modrm_addr): Support AMD64 instruction set 64 bits lea. (i386_record_lea_modrm): Ditto. (i386_record_push): New function. Record the execution log of push. (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the register. (i386_process_record): Support AMD64 instruction set. * amd64-tdep.c (amd64_record_regmap): For record_regmap. (amd64_init_abi): Set amd64_record_regmap to record_regmap. Thanks, Hui ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-19 17:21 ` Hui Zhu ` (2 preceding siblings ...) 2009-07-25 22:07 ` Michael Snyder @ 2009-07-25 22:20 ` Michael Snyder 2009-07-28 11:03 ` Hui Zhu 3 siblings, 1 reply; 15+ messages in thread From: Michael Snyder @ 2009-07-25 22:20 UTC (permalink / raw) To: Hui Zhu; +Cc: Mark Kettenis, gdb-patches ml Hui Zhu wrote: > On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: >> Mark Kettenis should approve it, though. >> > > > Thanks Michael. > > I update the patches according to your mail except changelog. Because > It sames that we just add * at the begin of the function name. > > Please help me review it. > > Thanks, > Hui > > 2009-07-20 Hui Zhu <teawater@gmail.com> > > Add AMD64 process record instruction set support. > > * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers > because the AMD64's registers order in GDB is not same with > I386 instructions. > Add i386_syscall_record to be the syscall function handle > interface. > (record_i386_regnum): Number for record_regmap. > * i386-tdep.c (OT_QUAD): For 64 bits. > (i386_record_s): Add rex_x, rex_b, rip_offset and > popl_esp_hack for AMD64 instruction set. And regmap for > record_regmap. > (i386_record_lea_modrm_addr): Support AMD64 instruction set > 64 bits lea. > (i386_record_lea_modrm): Ditto. > (i386_record_push): New function. Record the execution log > of push. > (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the > register. > (i386_process_record): Support AMD64 instruction set. > amd64-tdep.c (amd64_record_regmap): For record_regmap. > (amd64_init_abi): Set amd64_record_regmap to record_regmap. * amd64-tdep.c (...): Except for this small nit with the changelog, I have no further issues with this patch. Thanks for all your revisions (and your hard work)! Mark? You have the final say... ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-25 22:20 ` Michael Snyder @ 2009-07-28 11:03 ` Hui Zhu 2009-08-03 5:37 ` Hui Zhu 0 siblings, 1 reply; 15+ messages in thread From: Hui Zhu @ 2009-07-28 11:03 UTC (permalink / raw) To: Mark Kettenis; +Cc: Michael Snyder, gdb-patches ml Hi Mark, Could you please help me review this patch? Thanks, Hui On Sun, Jul 26, 2009 at 06:00, Michael Snyder<msnyder@vmware.com> wrote: > Hui Zhu wrote: >> >> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: > >>> Mark Kettenis should approve it, though. >>> >> >> >> Thanks Michael. >> >> I update the patches according to your mail except changelog. Because >> It sames that we just add * at the begin of the function name. >> >> Please help me review it. >> >> Thanks, >> Hui >> >> 2009-07-20 Hui Zhu <teawater@gmail.com> >> >> Add AMD64 process record instruction set support. >> >> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >> because the AMD64's registers order in GDB is not same with >> I386 instructions. >> Add i386_syscall_record to be the syscall function handle >> interface. >> (record_i386_regnum): Number for record_regmap. >> * i386-tdep.c (OT_QUAD): For 64 bits. >> (i386_record_s): Add rex_x, rex_b, rip_offset and >> popl_esp_hack for AMD64 instruction set. And regmap for >> record_regmap. >> (i386_record_lea_modrm_addr): Support AMD64 instruction set >> 64 bits lea. >> (i386_record_lea_modrm): Ditto. >> (i386_record_push): New function. Record the execution log >> of push. >> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >> register. >> (i386_process_record): Support AMD64 instruction set. >> amd64-tdep.c (amd64_record_regmap): For record_regmap. >> (amd64_init_abi): Set amd64_record_regmap to record_regmap. > > * amd64-tdep.c (...): > > Except for this small nit with the changelog, > I have no further issues with this patch. > Thanks for all your revisions (and your hard work)! > > Mark? You have the final say... > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 2009-07-28 11:03 ` Hui Zhu @ 2009-08-03 5:37 ` Hui Zhu 0 siblings, 0 replies; 15+ messages in thread From: Hui Zhu @ 2009-08-03 5:37 UTC (permalink / raw) To: Mark Kettenis; +Cc: Michael Snyder, gdb-patches ml Ping. On Tue, Jul 28, 2009 at 09:42, Hui Zhu<teawater@gmail.com> wrote: > Hi Mark, > > Could you please help me review this patch? > > Thanks, > Hui > > On Sun, Jul 26, 2009 at 06:00, Michael Snyder<msnyder@vmware.com> wrote: >> Hui Zhu wrote: >>> >>> On Sat, Jul 18, 2009 at 07:53, Michael Snyder<msnyder@vmware.com> wrote: >> >>>> Mark Kettenis should approve it, though. >>>> >>> >>> >>> Thanks Michael. >>> >>> I update the patches according to your mail except changelog. Because >>> It sames that we just add * at the begin of the function name. >>> >>> Please help me review it. >>> >>> Thanks, >>> Hui >>> >>> 2009-07-20 Hui Zhu <teawater@gmail.com> >>> >>> Add AMD64 process record instruction set support. >>> >>> * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers >>> because the AMD64's registers order in GDB is not same with >>> I386 instructions. >>> Add i386_syscall_record to be the syscall function handle >>> interface. >>> (record_i386_regnum): Number for record_regmap. >>> * i386-tdep.c (OT_QUAD): For 64 bits. >>> (i386_record_s): Add rex_x, rex_b, rip_offset and >>> popl_esp_hack for AMD64 instruction set. And regmap for >>> record_regmap. >>> (i386_record_lea_modrm_addr): Support AMD64 instruction set >>> 64 bits lea. >>> (i386_record_lea_modrm): Ditto. >>> (i386_record_push): New function. Record the execution log >>> of push. >>> (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the >>> register. >>> (i386_process_record): Support AMD64 instruction set. >>> amd64-tdep.c (amd64_record_regmap): For record_regmap. >>> (amd64_init_abi): Set amd64_record_regmap to record_regmap. >> >> * amd64-tdep.c (...): >> >> Except for this small nit with the changelog, >> I have no further issues with this patch. >> Thanks for all your revisions (and your hard work)! >> >> Mark? You have the final say... >> >> > ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2009-08-03 5:37 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-07-07 2:38 [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3 Hui Zhu 2009-07-13 0:52 ` Michael Snyder 2009-07-17 8:50 ` Hui Zhu 2009-07-18 1:20 ` Michael Snyder 2009-07-19 17:21 ` Hui Zhu 2009-07-19 21:22 ` Mark Kettenis 2009-07-20 6:14 ` Hui Zhu 2009-07-20 1:39 ` Michael Snyder 2009-07-20 10:22 ` Hui Zhu 2009-07-20 14:24 ` Hui Zhu 2009-07-25 22:07 ` Michael Snyder 2009-07-27 16:50 ` Hui Zhu 2009-07-25 22:20 ` Michael Snyder 2009-07-28 11:03 ` Hui Zhu 2009-08-03 5:37 ` Hui Zhu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox