OT_BYTE = 0,
OT_WORD,
OT_LONG,
+ OT_QUAD,
};
/* i386 arith/logic operations */
struct i386_record_s
{
+ struct gdbarch *gdbarch;
struct regcache *regcache;
CORE_ADDR addr;
int aflag;
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
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))
{
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)
}
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)
{
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 "
return -1;
}
irp->addr += 4;
+ *addr = tmpi32;
+ if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+ *addr += irp->addr + irp->rip_offset;
}
else
{
*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 "
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
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 "
return -1;
}
irp->addr += 2;
- *addr = (int16_t) tmpu16;
+ *addr = tmpi16;
irp->rm = 0;
goto no_rm;
}
*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 "
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;
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 "
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)
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 "
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;
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;
}
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 */
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 */
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 */
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)
}
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:
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;
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)
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))
}
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;
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 */
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 */
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 */
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 */
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 */
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 */
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;
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 */
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:
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;
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ ir.rm != ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
+ ir.rm &= 0x3;
+ 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 */
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 */
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))
}
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:
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)
{
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;
}
{
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;
}
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:
/* 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 */
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:
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 */
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))
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 */
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 */
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 */
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 */
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 */
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 "
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 */
/* 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;
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;
/* sgdt */
case 0:
{
- uint32_t addr;
+ uint64_t tmpu64;
if (ir.mod == 3)
{
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 "
}
else
{
- 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))
- 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;
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;
else
{
/* sidt */
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
}
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;
case 2:
/* lidt */
case 3:
- /* invlpg */
- case 7:
- default:
if (ir.mod == 3)
{
ir.addr -= 3;
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
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;
/* 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 */
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) */
return -1;
if ((ir.modrm & 0xc0) != 0xc0)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
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;
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 */
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;
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)
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